GCC Code Coverage Report


Directory: ./
File: sql/sql_base.cc
Date: 2022-12-13 11:44:05
Exec Total Coverage
Lines: 3359 3621 92.8%
Branches: 4276 6496 65.8%

Line Branch Exec Source
1 /* Copyright (c) 2000, 2022, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /* Basic functions needed by many modules */
24
25 #include "sql/sql_base.h"
26
27 #include <fcntl.h>
28 #include <limits.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <time.h>
32 #include <atomic>
33 #include <functional>
34 #include <memory>
35 #include <unordered_map>
36 #include <utility>
37
38 #include "ft_global.h"
39 #include "libbinlogevents/include/table_id.h"
40 #include "m_ctype.h"
41 #include "m_string.h"
42 #include "map_helpers.h"
43 #include "mf_wcomp.h" // wild_one, wild_many
44 #include "mutex_lock.h"
45 #include "my_alloc.h"
46 #include "my_bitmap.h"
47 #include "my_byteorder.h"
48 #include "my_compiler.h"
49 #include "my_dbug.h"
50 #include "my_dir.h"
51 #include "my_io.h"
52 #include "my_loglevel.h"
53 #include "my_macros.h"
54 #include "my_psi_config.h"
55 #include "my_sqlcommand.h"
56 #include "my_sys.h"
57 #include "my_systime.h"
58 #include "my_table_map.h"
59 #include "my_thread_local.h"
60 #include "mysql/components/services/bits/mysql_cond_bits.h"
61 #include "mysql/components/services/bits/psi_bits.h"
62 #include "mysql/components/services/bits/psi_cond_bits.h"
63 #include "mysql/components/services/bits/psi_mutex_bits.h"
64 #include "mysql/components/services/log_builtins.h"
65 #include "mysql/plugin.h"
66 #include "mysql/psi/mysql_cond.h"
67 #include "mysql/psi/mysql_file.h"
68 #include "mysql/psi/mysql_mutex.h"
69 #include "mysql/psi/mysql_statement.h"
70 #include "mysql/psi/mysql_table.h"
71 #include "mysql/psi/mysql_thread.h"
72 #include "mysql/psi/psi_table.h"
73 #include "mysql/service_mysql_alloc.h"
74 #include "mysql/thread_type.h"
75 #include "mysql_com.h"
76 #include "mysqld_error.h"
77 #include "sql/auth/auth_acls.h"
78 #include "sql/auth/auth_common.h" // check_table_access
79 #include "sql/auth/sql_security_ctx.h"
80 #include "sql/binlog.h" // mysql_bin_log
81 #include "sql/check_stack.h"
82 #include "sql/dd/cache/dictionary_client.h"
83 #include "sql/dd/dd.h" // dd::get_dictionary()
84 #include "sql/dd/dd_schema.h"
85 #include "sql/dd/dd_table.h" // dd::table_exists
86 #include "sql/dd/dd_tablespace.h" // dd::fill_table_and_parts_tablespace_name
87 #include "sql/dd/dictionary.h"
88 #include "sql/dd/string_type.h"
89 #include "sql/dd/types/abstract_table.h"
90 #include "sql/dd/types/column.h"
91 #include "sql/dd/types/column_statistics.h"
92 #include "sql/dd/types/foreign_key.h" // dd::Foreign_key
93 #include "sql/dd/types/function.h"
94 #include "sql/dd/types/procedure.h"
95 #include "sql/dd/types/schema.h"
96 #include "sql/dd/types/table.h" // dd::Table
97 #include "sql/dd/types/view.h"
98 #include "sql/dd_table_share.h" // open_table_def
99 #include "sql/debug_sync.h" // DEBUG_SYNC
100 #include "sql/derror.h" // ER_THD
101 #include "sql/error_handler.h" // Internal_error_handler
102 #include "sql/field.h"
103 #include "sql/handler.h"
104 #include "sql/histograms/histogram.h"
105 #include "sql/item.h"
106 #include "sql/item_cmpfunc.h" // Item_func_eq
107 #include "sql/item_func.h"
108 #include "sql/item_subselect.h"
109 #include "sql/lock.h" // mysql_lock_remove
110 #include "sql/log.h"
111 #include "sql/log_event.h" // Query_log_event
112 #include "sql/mysqld.h" // replica_open_temp_tables
113 #include "sql/mysqld_thd_manager.h" // Global_THD_manage
114 #include "sql/nested_join.h"
115 #include "sql/partition_info.h" // partition_info
116 #include "sql/psi_memory_key.h" // key_memory_TABLE
117 #include "sql/query_options.h"
118 #include "sql/rpl_gtid.h"
119 #include "sql/rpl_handler.h" // RUN_HOOK
120 #include "sql/rpl_replica_commit_order_manager.h" // has_commit_order_manager
121 #include "sql/rpl_rli.h" //Relay_log_information
122 #include "sql/session_tracker.h"
123 #include "sql/sp.h" // Sroutine_hash_entry
124 #include "sql/sp_cache.h" // sp_cache_version
125 #include "sql/sp_head.h" // sp_head
126 #include "sql/sql_audit.h" // mysql_audit_table_access_notify
127 #include "sql/sql_backup_lock.h" // acquire_shared_backup_lock
128 #include "sql/sql_class.h" // THD
129 #include "sql/sql_const.h"
130 #include "sql/sql_data_change.h"
131 #include "sql/sql_db.h" // check_schema_readonly
132 #include "sql/sql_error.h" // Sql_condition
133 #include "sql/sql_handler.h" // mysql_ha_flush_tables
134 #include "sql/sql_lex.h"
135 #include "sql/sql_list.h"
136 #include "sql/sql_parse.h" // is_update_query
137 #include "sql/sql_prepare.h" // Reprepare_observer
138 #include "sql/sql_select.h" // reset_statement_timer
139 #include "sql/sql_show.h" // append_identifier
140 #include "sql/sql_sort.h"
141 #include "sql/sql_table.h" // build_table_filename
142 #include "sql/sql_update.h" // records_are_comparable
143 #include "sql/sql_view.h" // mysql_make_view
144 #include "sql/strfunc.h"
145 #include "sql/system_variables.h"
146 #include "sql/table.h" // TABLE_LIST
147 #include "sql/table_cache.h" // table_cache_manager
148 #include "sql/table_trigger_dispatcher.h" // Table_trigger_dispatcher
149 #include "sql/thd_raii.h"
150 #include "sql/transaction.h" // trans_rollback_stmt
151 #include "sql/transaction_info.h"
152 #include "sql/trigger_chain.h" // Trigger_chain
153 #include "sql/xa.h"
154 #include "sql_string.h"
155 #include "template_utils.h"
156 #include "thr_mutex.h"
157
158 #ifdef WITH_WSREP
159 #include "wsrep_mysqld.h"
160 #include "wsrep_thd.h"
161 #include "wsrep_trans_observer.h"
162 #endif /* WITH_WSREP */
163
164 using std::equal_to;
165 using std::hash;
166 using std::pair;
167 using std::string;
168 using std::unique_ptr;
169 using std::unordered_map;
170
171 /**
172 The maximum length of a key in the table definition cache.
173
174 The key consists of the schema name, a '\0' character, the table
175 name and a '\0' character. Hence NAME_LEN * 2 + 1 + 1.
176
177 Additionally, the key can be suffixed with either 4 + 4 extra bytes
178 for slave tmp tables, or with a single extra byte for tables in a
179 secondary storage engine. Add 4 + 4 to account for either of these
180 suffixes.
181 */
182 static constexpr const size_t MAX_DBKEY_LENGTH{NAME_LEN * 2 + 1 + 1 + 4 + 4};
183
184 static constexpr long STACK_MIN_SIZE_FOR_OPEN{1024 * 80};
185
186 /**
187 This internal handler is used to trap ER_NO_SUCH_TABLE and
188 ER_WRONG_MRG_TABLE errors during CHECK/REPAIR TABLE for MERGE
189 tables.
190 */
191
192 class Repair_mrg_table_error_handler : public Internal_error_handler {
193 public:
194 2 Repair_mrg_table_error_handler()
195 2 : m_handled_errors(false), m_unhandled_errors(false) {}
196
197 1 bool handle_condition(THD *, uint sql_errno, const char *,
198 Sql_condition::enum_severity_level *,
199 const char *) override {
200
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (sql_errno == ER_NO_SUCH_TABLE || sql_errno == ER_WRONG_MRG_TABLE) {
201 1 m_handled_errors = true;
202 1 return true;
203 }
204
205 m_unhandled_errors = true;
206 return false;
207 }
208
209 /**
210 Returns true if there were ER_NO_SUCH_/WRONG_MRG_TABLE and there
211 were no unhandled errors. false otherwise.
212 */
213 2 bool safely_trapped_errors() {
214 /*
215 Check for m_handled_errors is here for extra safety.
216 It can be useful in situation when call to open_table()
217 fails because some error which was suppressed by another
218 error handler (e.g. in case of MDL deadlock which we
219 decided to solve by back-off and retry).
220 */
221
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 return (m_handled_errors && (!m_unhandled_errors));
222 }
223
224 private:
225 bool m_handled_errors;
226 bool m_unhandled_errors;
227 };
228
229 /**
230 @defgroup Data_Dictionary Data Dictionary
231 @{
232 */
233
234 /**
235 LOCK_open protects the following variables/objects:
236
237 1) The table_def_cache
238 This is the hash table mapping table name to a table
239 share object. The hash table can only be manipulated
240 while holding LOCK_open.
241 2) last_table_id
242 Generation of a new unique table_map_id for a table
243 share is done through incrementing last_table_id, a
244 global variable used for this purpose.
245 3) LOCK_open protects the initialisation of the table share
246 object and all its members, however, it does not protect
247 reading the .frm file from where the table share is
248 initialised. In get_table_share, the lock is temporarily
249 released while opening the table definition in order to
250 allow a higher degree of concurrency. Concurrent access
251 to the same share is controlled by introducing a condition
252 variable for signaling when opening the share is completed.
253 4) In particular the share->ref_count is updated each time
254 a new table object is created that refers to a table share.
255 This update is protected by LOCK_open.
256 5) oldest_unused_share, end_of_unused_share and share->next
257 and share->prev are variables to handle the lists of table
258 share objects, these can only be read and manipulated while
259 holding the LOCK_open mutex.
260 6) table_def_shutdown_in_progress can be updated only while
261 holding LOCK_open and ALL table cache mutexes.
262 7) refresh_version
263 This variable can only be updated while holding LOCK_open AND
264 all table cache mutexes.
265 8) share->version
266 This variable is initialised while holding LOCK_open. It can only
267 be updated while holding LOCK_open AND all table cache mutexes.
268 So if a table share is found through a reference its version won't
269 change if any of those mutexes are held.
270 9) share->m_flush_tickets
271 */
272
273 mysql_mutex_t LOCK_open;
274
275 /**
276 COND_open synchronizes concurrent opening of the same share:
277
278 If a thread calls get_table_share, it releases the LOCK_open
279 mutex while reading the definition from file. If a different
280 thread calls get_table_share for the same share at this point
281 in time, it will find the share in the TDC, but with the
282 m_open_in_progress flag set to true. This will make the
283 (second) thread wait for the COND_open condition, while the
284 first thread completes opening the table definition.
285
286 When the first thread is done reading the table definition,
287 it will set m_open_in_progress to false and broadcast the
288 COND_open condition. Then, all threads waiting for COND_open
289 will wake up and, re-search the TDC for the share, and:
290
291 1) If the share is gone, the thread will continue to allocate
292 and open the table definition. This happens, e.g., if the
293 first thread failed when opening the table definition and
294 had to destroy the share.
295 2) If the share is still in the cache, and m_open_in_progress
296 is still true, the thread will wait for the condition again.
297 This happens if a different thread finished opening a
298 different share.
299 3) If the share is still in the cache, and m_open_in_progress
300 has become false, the thread will check if the share is ok
301 (no error), increment the ref counter, and return the share.
302 */
303
304 mysql_cond_t COND_open;
305
306 #ifdef HAVE_PSI_INTERFACE
307 static PSI_mutex_key key_LOCK_open;
308 static PSI_cond_key key_COND_open;
309 static PSI_mutex_info all_tdc_mutexes[] = {
310 {&key_LOCK_open, "LOCK_open", PSI_FLAG_SINGLETON, 0, PSI_DOCUMENT_ME}};
311 static PSI_cond_info all_tdc_conds[] = {
312 {&key_COND_open, "COND_open", 0, 0, PSI_DOCUMENT_ME}};
313
314 /**
315 Initialize performance schema instrumentation points
316 used by the table cache.
317 */
318
319 9775 static void init_tdc_psi_keys(void) {
320 9775 const char *category = "sql";
321 int count;
322
323 9775 count = static_cast<int>(array_elements(all_tdc_mutexes));
324 9775 mysql_mutex_register(category, all_tdc_mutexes, count);
325
326 9775 count = static_cast<int>(array_elements(all_tdc_conds));
327 9775 mysql_cond_register(category, all_tdc_conds, count);
328 9775 }
329 #endif /* HAVE_PSI_INTERFACE */
330
331 using Table_definition_cache =
332 malloc_unordered_map<std::string,
333 std::unique_ptr<TABLE_SHARE, Table_share_deleter>>;
334 Table_definition_cache *table_def_cache;
335 static TABLE_SHARE *oldest_unused_share, end_of_unused_share;
336 static bool table_def_shutdown_in_progress = false;
337
338 static bool check_and_update_table_version(THD *thd, TABLE_LIST *tables,
339 TABLE_SHARE *table_share);
340 static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share,
341 const dd::Table *table, TABLE *entry);
342 static bool auto_repair_table(THD *thd, TABLE_LIST *table_list);
343 static TABLE *find_temporary_table(THD *thd, const char *table_key,
344 size_t table_key_length);
345 static bool tdc_open_view(THD *thd, TABLE_LIST *table_list,
346 const char *cache_key, size_t cache_key_length);
347 static bool add_view_place_holder(THD *thd, TABLE_LIST *table_list);
348
349 /**
350 Create a table cache/table definition cache key for a table. The
351 table is neither a temporary table nor a table in a secondary
352 storage engine.
353
354 @note
355 The table cache_key is created from:
356
357 db_name + \0
358 table_name + \0
359
360 @param[in] db_name the database name
361 @param[in] table_name the table name
362 @param[out] key buffer for the key to be created (must be of
363 size MAX_DBKEY_LENGTH)
364 @return the length of the key
365 */
366 3982232 static size_t create_table_def_key(const char *db_name, const char *table_name,
367 char *key) {
368 /*
369 In theory caller should ensure that both db and table_name are
370 not longer than NAME_LEN bytes. In practice we play safe to avoid
371 buffer overruns.
372 */
373
3/4
✓ Branch 0 taken 3982232 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3982231 times.
✓ Branch 3 taken 1 times.
3982232 assert(strlen(db_name) <= NAME_LEN && strlen(table_name) <= NAME_LEN);
374 3982231 return strmake(strmake(key, db_name, NAME_LEN) + 1, table_name, NAME_LEN) -
375 3982231 key + 1;
376 }
377
378 /**
379 Create a table cache/table definition cache key for a temporary table.
380
381 The key is constructed by appending the following to the key
382 generated by #create_table_def_key():
383
384 - 4 bytes for master thread id
385 - 4 bytes pseudo thread id
386
387 @param[in] thd thread context
388 @param[in] db_name the database name
389 @param[in] table_name the table name
390 @param[out] key buffer for the key to be created (must be of
391 size MAX_DBKEY_LENGTH)
392 @return the length of the key
393 */
394 346735 static size_t create_table_def_key_tmp(const THD *thd, const char *db_name,
395 const char *table_name, char *key) {
396 346735 size_t key_length = create_table_def_key(db_name, table_name, key);
397 346734 int4store(key + key_length, thd->server_id);
398 346734 int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
399 346734 return key_length + TMP_TABLE_KEY_EXTRA;
400 }
401
402 /**
403 Create a table cache/table definition cache key for a table in a
404 secondary storage engine.
405
406 The key is constructed by appending a single byte with the value 1
407 to the key generated by #create_table_def_key().
408
409 @param db_name the database name
410 @param table_name the table name
411 @return the key
412 */
413 1395922 static std::string create_table_def_key_secondary(const char *db_name,
414 const char *table_name) {
415 char key[MAX_DBKEY_LENGTH];
416
1/2
✓ Branch 0 taken 1395922 times.
✗ Branch 1 not taken.
1395922 size_t key_length = create_table_def_key(db_name, table_name, key);
417 // Add a single byte to distinguish the secondary table from the
418 // primary table. Their db name and table name are identical.
419 1395922 key[key_length++] = 1;
420
1/2
✓ Branch 0 taken 1395922 times.
✗ Branch 1 not taken.
1395922 return {key, key_length};
421 }
422
423 /**
424 Get table cache key for a table list element.
425
426 @param [in] table_list Table list element.
427 @param [out] key On return points to table cache key for the table.
428
429 @note Unlike create_table_def_key() call this function doesn't construct
430 key in a buffer provider by caller. Instead it relies on the fact
431 that table list element for which key is requested has properly
432 initialized MDL_request object and the fact that table definition
433 cache key is suffix of key used in MDL subsystem. So to get table
434 definition key it simply needs to return pointer to appropriate
435 part of MDL_key object nested in this table list element.
436 Indeed, this means that lifetime of key produced by this call is
437 limited by the lifetime of table list element which it got as
438 parameter.
439
440 @return Length of key.
441 */
442
443 120044921 size_t get_table_def_key(const TABLE_LIST *table_list, const char **key) {
444 /*
445 This call relies on the fact that TABLE_LIST::mdl_request::key object
446 is properly initialized, so table definition cache can be produced
447 from key used by MDL subsystem.
448 strcase is converted to strcasecmp because information_schema tables
449 can be accessed with lower case and upper case table names.
450 */
451
2/6
✓ Branch 0 taken 120047326 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 120047690 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
120044921 assert(
452 !my_strcasecmp(system_charset_info, table_list->get_db_name(),
453 table_list->mdl_request.key.db_name()) &&
454 #ifdef WITH_WSREP
455 (!my_strcasecmp(system_charset_info, table_list->get_table_name(),
456 table_list->mdl_request.key.name()) ||
457 !my_strcasecmp(system_charset_info, table_list->get_table_alias(),
458 table_list->mdl_request.key.name())));
459 #else
460 !my_strcasecmp(system_charset_info, table_list->get_table_name(),
461 table_list->mdl_request.key.name()));
462 #endif /* WITH_WSREP */
463
464 120047584 *key = (const char *)table_list->mdl_request.key.ptr() + 1;
465 120046674 return table_list->mdl_request.key.length() - 1;
466 }
467
468 /*****************************************************************************
469 Functions to handle table definition cache (TABLE_SHARE)
470 *****************************************************************************/
471
472 2059148 void Table_share_deleter::operator()(TABLE_SHARE *share) const {
473
1/2
✓ Branch 0 taken 2059148 times.
✗ Branch 1 not taken.
2059148 DBUG_TRACE;
474 mysql_mutex_assert_owner(&LOCK_open);
475
2/2
✓ Branch 0 taken 266548 times.
✓ Branch 1 taken 1792600 times.
2059148 if (share->prev) {
476 /* remove from old_unused_share list */
477 266548 *share->prev = share->next;
478 266548 share->next->prev = share->prev;
479 }
480
1/2
✓ Branch 0 taken 2059148 times.
✗ Branch 1 not taken.
2059148 free_table_share(share);
481 2059148 }
482
483 9775 bool table_def_init(void) {
484 #ifdef HAVE_PSI_INTERFACE
485 9775 init_tdc_psi_keys();
486 #endif
487 9775 mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST);
488 9775 mysql_cond_init(key_COND_open, &COND_open);
489 9775 oldest_unused_share = &end_of_unused_share;
490 9775 end_of_unused_share.prev = &oldest_unused_share;
491
492
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9775 times.
9775 if (table_cache_manager.init()) {
493 mysql_cond_destroy(&COND_open);
494 mysql_mutex_destroy(&LOCK_open);
495 return true;
496 }
497
498
1/2
✓ Branch 0 taken 9775 times.
✗ Branch 1 not taken.
9775 table_def_cache = new Table_definition_cache(key_memory_table_share);
499 9775 return false;
500 }
501
502 /**
503 Notify table definition cache that process of shutting down server
504 has started so it has to keep number of TABLE and TABLE_SHARE objects
505 minimal in order to reduce number of references to pluggable engines.
506 */
507
508 8457 void table_def_start_shutdown(void) {
509
2/2
✓ Branch 0 taken 8403 times.
✓ Branch 1 taken 54 times.
8457 if (table_def_cache != nullptr) {
510 8403 table_cache_manager.lock_all_and_tdc();
511 /*
512 Ensure that TABLE and TABLE_SHARE objects which are created for
513 tables that are open during process of plugins' shutdown are
514 immediately released. This keeps number of references to engine
515 plugins minimal and allows shutdown to proceed smoothly.
516 */
517 8403 table_def_shutdown_in_progress = true;
518 8403 table_cache_manager.unlock_all_and_tdc();
519 /* Free all cached but unused TABLEs and TABLE_SHAREs. */
520 8403 close_cached_tables(nullptr, nullptr, false, LONG_TIMEOUT);
521 }
522 8457 }
523
524 8473 void table_def_free(void) {
525
1/2
✓ Branch 0 taken 8473 times.
✗ Branch 1 not taken.
8473 DBUG_TRACE;
526
2/2
✓ Branch 0 taken 8419 times.
✓ Branch 1 taken 54 times.
8473 if (table_def_cache != nullptr) {
527 /* Free table definitions. */
528
1/2
✓ Branch 0 taken 8419 times.
✗ Branch 1 not taken.
8419 delete table_def_cache;
529 8419 table_def_cache = nullptr;
530
1/2
✓ Branch 0 taken 8419 times.
✗ Branch 1 not taken.
8419 table_cache_manager.destroy();
531
1/2
✓ Branch 0 taken 8419 times.
✗ Branch 1 not taken.
8419 mysql_cond_destroy(&COND_open);
532
1/2
✓ Branch 0 taken 8419 times.
✗ Branch 1 not taken.
8419 mysql_mutex_destroy(&LOCK_open);
533 }
534 8473 }
535
536 142363 uint cached_table_definitions(void) { return table_def_cache->size(); }
537
538 2165838 static TABLE_SHARE *process_found_table_share(THD *thd [[maybe_unused]],
539 TABLE_SHARE *share,
540 bool open_view) {
541
1/2
✓ Branch 0 taken 2165838 times.
✗ Branch 1 not taken.
2165838 DBUG_TRACE;
542 mysql_mutex_assert_owner(&LOCK_open);
543 #if defined(ENABLED_DEBUG_SYNC)
544
3/4
✓ Branch 0 taken 2165838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1307947 times.
✓ Branch 3 taken 857891 times.
2165838 if (!thd->is_attachable_ro_transaction_active())
545
3/4
✓ Branch 0 taken 1290111 times.
✓ Branch 1 taken 17836 times.
✓ Branch 2 taken 1290111 times.
✗ Branch 3 not taken.
1307947 DEBUG_SYNC(thd, "get_share_found_share");
546 #endif
547 /*
548 We found an existing table definition. Return it if we didn't get
549 an error when reading the table definition from file.
550 */
551
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2165838 times.
2165838 if (share->error) {
552 /*
553 Table definition contained an error.
554 Note that we report ER_NO_SUCH_TABLE regardless of which error occurred
555 when the other thread tried to open the table definition (e.g. OOM).
556 */
557 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
558 return nullptr;
559 }
560
3/4
✓ Branch 0 taken 385613 times.
✓ Branch 1 taken 1780225 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 385613 times.
2165838 if (share->is_view && !open_view) {
561 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
562 return nullptr;
563 }
564
565
1/2
✓ Branch 0 taken 2165838 times.
✗ Branch 1 not taken.
2165838 share->increment_ref_count();
566
567
6/8
✓ Branch 0 taken 2165838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 561298 times.
✓ Branch 3 taken 1604540 times.
✓ Branch 4 taken 561298 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 561298 times.
✓ Branch 7 taken 1604540 times.
2165838 if (share->ref_count() == 1 && share->prev) {
568 /*
569 Share was not used before and it was in the old_unused_share list
570 Unlink share from this list
571 */
572
5/8
✓ Branch 0 taken 561298 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 561298 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 561281 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
561298 DBUG_PRINT("info", ("Unlinking from not used list"));
573 561298 *share->prev = share->next;
574 561298 share->next->prev = share->prev;
575 561298 share->next = nullptr;
576 561298 share->prev = nullptr;
577 }
578
579 /* Free cache if too big */
580
6/6
✓ Branch 0 taken 1312 times.
✓ Branch 1 taken 2164645 times.
✓ Branch 2 taken 119 times.
✓ Branch 3 taken 1193 times.
✓ Branch 4 taken 119 times.
✓ Branch 5 taken 2165838 times.
2165957 while (table_def_cache->size() > table_def_size && oldest_unused_share->next)
581
2/4
✓ Branch 0 taken 119 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 119 times.
✗ Branch 3 not taken.
119 table_def_cache->erase(to_string(oldest_unused_share->table_cache_key));
582
583
6/10
✓ Branch 0 taken 2165838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2165838 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 2165818 times.
✓ Branch 6 taken 20 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20 times.
✗ Branch 9 not taken.
2165838 DBUG_PRINT("exit", ("share: %p ref_count: %u", share, share->ref_count()));
584 2165838 return share;
585 2165838 }
586
587 /**
588 Read any existing histogram statistics from the data dictionary and
589 store a copy of them in the TABLE_SHARE.
590
591 @param thd Thread handler
592 @param share The table share where to store the histograms
593 @param schema Schema definition
594 @param table_def Table definition
595
596 @retval true on error
597 @retval false on success
598 */
599 1909257 static bool read_histograms(THD *thd, TABLE_SHARE *share,
600 const dd::Schema *schema,
601 const dd::Abstract_table *table_def) {
602
1/2
✓ Branch 0 taken 1909265 times.
✗ Branch 1 not taken.
1909257 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
603
1/2
✓ Branch 0 taken 1909262 times.
✗ Branch 1 not taken.
1909265 MDL_request_list mdl_requests;
604
6/10
✓ Branch 0 taken 1909264 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1909263 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1909265 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20852167 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20852165 times.
✓ Branch 9 taken 1909267 times.
22761428 for (const auto column : table_def->columns()) {
605
3/4
✓ Branch 0 taken 20852166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3332329 times.
✓ Branch 3 taken 17519837 times.
20852167 if (column->is_se_hidden()) continue;
606
607 17519837 MDL_key mdl_key;
608
3/6
✓ Branch 0 taken 17519838 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17519837 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17519835 times.
✗ Branch 5 not taken.
17519836 dd::Column_statistics::create_mdl_key(schema->name(), table_def->name(),
609
1/2
✓ Branch 0 taken 17519836 times.
✗ Branch 1 not taken.
17519837 column->name(), &mdl_key);
610
611
1/2
✓ Branch 0 taken 17519839 times.
✗ Branch 1 not taken.
17519835 MDL_request *request = new (thd->mem_root) MDL_request;
612
1/2
✓ Branch 0 taken 17519839 times.
✗ Branch 1 not taken.
17519833 MDL_REQUEST_INIT_BY_KEY(request, &mdl_key, MDL_SHARED_READ, MDL_STATEMENT);
613
1/2
✓ Branch 0 taken 17519837 times.
✗ Branch 1 not taken.
17519839 mdl_requests.push_front(request);
614 }
615
616
2/4
✓ Branch 0 taken 1909265 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1909265 times.
1909267 if (thd->mdl_context.acquire_locks(&mdl_requests,
617 thd->variables.lock_wait_timeout))
618 return true; /* purecov: deadcode */
619
620
6/10
✓ Branch 0 taken 1909265 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1909265 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1909265 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20852158 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20852163 times.
✓ Branch 9 taken 1909264 times.
22761422 for (const auto column : table_def->columns()) {
621
3/4
✓ Branch 0 taken 20852156 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3332328 times.
✓ Branch 3 taken 17519828 times.
20852158 if (column->is_se_hidden()) continue;
622
623 17519828 const histograms::Histogram *histogram = nullptr;
624
6/12
✓ Branch 0 taken 17519829 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17519835 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17519825 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 17519841 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 17519807 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 17519829 times.
52559492 if (histograms::find_histogram(thd, schema->name().c_str(),
625
1/2
✓ Branch 0 taken 17519816 times.
✗ Branch 1 not taken.
17519830 table_def->name().c_str(),
626
1/2
✓ Branch 0 taken 17519811 times.
✗ Branch 1 not taken.
17519829 column->name().c_str(), &histogram)) {
627 // Any error is reported by the dictionary subsystem.
628 return true; /* purecov: deadcode */
629 }
630
631
2/2
✓ Branch 0 taken 497 times.
✓ Branch 1 taken 17519332 times.
17519829 if (histogram != nullptr) {
632 /*
633 Make a clone of the histogram so it survives together with the
634 TABLE_SHARE in case the original histogram is thrown out of the
635 dictionary cache.
636 */
637 const histograms::Histogram *histogram_copy =
638
1/2
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
497 histogram->clone(&share->mem_root);
639
2/4
✓ Branch 0 taken 497 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 497 times.
✗ Branch 3 not taken.
497 share->m_histograms->emplace(column->ordinal_position() - 1,
640 histogram_copy);
641 }
642 }
643
644 1909264 return false;
645 1909264 }
646
647 /** Update TABLE_SHARE with options from dd::Schema object */
648 1909260 static void update_schema_options(const dd::Schema *sch_obj,
649 TABLE_SHARE *share) {
650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1909260 times.
1909260 assert(sch_obj != nullptr);
651
1/2
✓ Branch 0 taken 1909260 times.
✗ Branch 1 not taken.
1909260 if (sch_obj != nullptr) {
652
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 1909220 times.
1909260 if (sch_obj->read_only())
653 43 share->schema_read_only = TABLE_SHARE::Schema_read_only::RO_ON;
654 else
655 1909220 share->schema_read_only = TABLE_SHARE::Schema_read_only::RO_OFF;
656 }
657 1909263 }
658
659 /**
660 Get the TABLE_SHARE for a table.
661
662 Get a table definition from the table definition cache. If the share
663 does not exist, create a new one from the persistently stored table
664 definition, and temporarily release LOCK_open while retrieving it.
665 Re-lock LOCK_open when the table definition has been retrieved, and
666 broadcast this to other threads waiting for the share to become opened.
667
668 If the share exists, and is in the process of being opened, wait for
669 opening to complete before continuing.
670
671 @pre It is a precondition that the caller must own LOCK_open before
672 calling this function.
673
674 @note Callers of this function cannot rely on LOCK_open being
675 held for the duration of the call. It may be temporarily
676 released while the table definition is opened, and it may be
677 temporarily released while the thread is waiting for a different
678 thread to finish opening it.
679
680 @note After share->m_open_in_progress is set, there should be no wait
681 for resources like row- or metadata locks, table flushes, etc.
682 Otherwise, we may end up in deadlocks that will not be detected.
683
684 @param thd thread handle
685 @param db schema name
686 @param table_name table name
687 @param key table cache key
688 @param key_length length of key
689 @param open_view allow open of view
690 @param open_secondary get the share for a table in a secondary
691 storage engine
692
693 @return Pointer to the new TABLE_SHARE, or NULL if there was an error
694 */
695
696 4292075 TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name,
697 const char *key, size_t key_length, bool open_view,
698 bool open_secondary) {
699 TABLE_SHARE *share;
700 4292075 bool open_table_err = false;
701
1/2
✓ Branch 0 taken 4292075 times.
✗ Branch 1 not taken.
4292075 DBUG_TRACE;
702
703 /* Make sure we own LOCK_open */
704 mysql_mutex_assert_owner(&LOCK_open);
705
706 /*
707 To be able perform any operation on table we should own
708 some kind of metadata lock on it.
709 */
710
2/4
✓ Branch 0 taken 4292075 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4292075 times.
4292075 assert(thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::TABLE, db,
711 table_name, MDL_SHARED));
712
713 /*
714 Read table definition from the cache. If the share is being opened,
715 wait for the appropriate condition. The share may be destroyed if
716 open fails, so after cond_wait, we must repeat searching the
717 hash table.
718 */
719 for (;;) {
720
2/4
✓ Branch 0 taken 5147553 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5147553 times.
✗ Branch 3 not taken.
5147553 auto it = table_def_cache->find(string(key, key_length));
721
2/2
✓ Branch 0 taken 2974195 times.
✓ Branch 1 taken 2173358 times.
5147553 if (it == table_def_cache->end()) {
722
3/4
✓ Branch 0 taken 2974195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2126236 times.
✓ Branch 3 taken 847959 times.
2974195 if (thd->mdl_context.owns_equal_or_stronger_lock(
723 MDL_key::SCHEMA, db, "", MDL_INTENTION_EXCLUSIVE)) {
724 2126236 break;
725 }
726
1/2
✓ Branch 0 taken 847959 times.
✗ Branch 1 not taken.
847959 mysql_mutex_unlock(&LOCK_open);
727
728
3/4
✓ Branch 0 taken 847959 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 847958 times.
847959 if (dd::mdl_lock_schema(thd, db, MDL_TRANSACTION)) {
729 // Lock LOCK_open again to preserve function contract
730
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_lock(&LOCK_open);
731 2165839 return nullptr;
732 }
733
734
1/2
✓ Branch 0 taken 847958 times.
✗ Branch 1 not taken.
847958 mysql_mutex_lock(&LOCK_open);
735 // Need to re-try the find after getting the mutex again
736 847958 continue;
737 }
738 2173358 share = it->second.get();
739
2/2
✓ Branch 0 taken 2165838 times.
✓ Branch 1 taken 7520 times.
2173358 if (!share->m_open_in_progress)
740
1/2
✓ Branch 0 taken 2165838 times.
✗ Branch 1 not taken.
2165838 return process_found_table_share(thd, share, open_view);
741
742
3/4
✓ Branch 0 taken 7389 times.
✓ Branch 1 taken 131 times.
✓ Branch 2 taken 7389 times.
✗ Branch 3 not taken.
7520 DEBUG_SYNC(thd, "get_share_before_COND_open_wait");
743
1/2
✓ Branch 0 taken 7520 times.
✗ Branch 1 not taken.
7520 mysql_cond_wait(&COND_open, &LOCK_open);
744 855478 }
745
746 /*
747 If alloc fails, the share object will not be present in the TDC, so no
748 thread will be waiting for m_open_in_progress. Hence, a broadcast is
749 not necessary.
750 */
751
2/4
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2126236 times.
2126236 if (!(share = alloc_table_share(db, table_name, key, key_length,
752 open_secondary))) {
753 return nullptr;
754 }
755
756 /*
757 We assign a new table id under the protection of LOCK_open.
758 We do this instead of creating a new mutex
759 and using it for the sole purpose of serializing accesses to a
760 static variable, we assign the table id here. We assign it to the
761 share before inserting it into the table_def_cache to be really
762 sure that it cannot be read from the cache without having a table
763 id assigned.
764
765 CAVEAT. This means that the table cannot be used for
766 binlogging/replication purposes, unless get_table_share() has been
767 called directly or indirectly.
768 */
769
1/2
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
2126236 assign_new_table_id(share);
770
771
2/4
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2126236 times.
✗ Branch 3 not taken.
2126236 table_def_cache->emplace(to_string(share->table_cache_key),
772 4252472 unique_ptr<TABLE_SHARE, Table_share_deleter>(share));
773
774 /*
775 We must increase ref_count prior to releasing LOCK_open
776 to keep the share from being deleted in tdc_remove_table()
777 and TABLE_SHARE::wait_for_old_version. We must also set
778 m_open_in_progress to indicate allocated but incomplete share.
779 */
780
1/2
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
2126236 share->increment_ref_count(); // Mark in use
781 2126236 share->m_open_in_progress = true; // Mark being opened
782
783 /*
784 Temporarily release LOCK_open before opening the table definition,
785 which can be done without mutex protection.
786 */
787
1/2
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
2126236 mysql_mutex_unlock(&LOCK_open);
788
789 #if defined(ENABLED_DEBUG_SYNC)
790
3/4
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1317348 times.
✓ Branch 3 taken 808888 times.
2126236 if (!thd->is_attachable_ro_transaction_active())
791
3/4
✓ Branch 0 taken 1274594 times.
✓ Branch 1 taken 42754 times.
✓ Branch 2 taken 1274594 times.
✗ Branch 3 not taken.
1317348 DEBUG_SYNC(thd, "get_share_before_open");
792 #endif
793
794 {
795 // We must make sure the schema is released and unlocked in the right order.
796
1/2
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
2126236 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
797 2126236 const dd::Schema *sch = nullptr;
798 2126236 const dd::Abstract_table *abstract_table = nullptr;
799 2126236 open_table_err = true; // Assume error to simplify code below.
800
4/10
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2126233 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2126234 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2126234 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
6378701 if (thd->dd_client()->acquire(share->db.str, &sch) ||
801
7/18
✓ Branch 0 taken 2126235 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2126235 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2126233 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2126233 times.
✓ Branch 8 taken 2126234 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2126233 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2126234 times.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
4252466 thd->dd_client()->acquire(share->db.str, share->table_name.str,
802 &abstract_table)) {
803
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 2126203 times.
2126234 } else if (sch == nullptr)
804
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 my_error(ER_BAD_DB_ERROR, MYF(0), share->db.str);
805
2/2
✓ Branch 0 taken 25384 times.
✓ Branch 1 taken 2100819 times.
2126203 else if (abstract_table == nullptr)
806
1/2
✓ Branch 0 taken 25384 times.
✗ Branch 1 not taken.
25384 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
807
5/6
✓ Branch 0 taken 2100814 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2017093 times.
✓ Branch 3 taken 83721 times.
✓ Branch 4 taken 191537 times.
✓ Branch 5 taken 1909280 times.
4117915 else if (abstract_table->type() == dd::enum_table_type::USER_VIEW ||
808
3/4
✓ Branch 0 taken 2017096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 107815 times.
✓ Branch 3 taken 1909281 times.
2017093 abstract_table->type() == dd::enum_table_type::SYSTEM_VIEW) {
809
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 191537 times.
191537 if (!open_view) // We found a view but were trying to open table only.
810 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str,
811 share->table_name.str);
812 else {
813 /*
814 Clone the view reference object and hold it in
815 TABLE_SHARE member view_object.
816 */
817 191537 share->is_view = true;
818 const dd::View *tmp_view =
819
1/2
✓ Branch 0 taken 191537 times.
✗ Branch 1 not taken.
191537 dynamic_cast<const dd::View *>(abstract_table);
820
1/2
✓ Branch 0 taken 191537 times.
✗ Branch 1 not taken.
191537 share->view_object = tmp_view->clone();
821
822 191537 share->table_category =
823
1/2
✓ Branch 0 taken 191537 times.
✗ Branch 1 not taken.
191537 get_table_category(share->db, share->table_name);
824 191537 thd->status_var.opened_shares++;
825 191537 open_table_err = false;
826 }
827 } else {
828
2/4
✓ Branch 0 taken 1909281 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1909281 times.
1909280 assert(abstract_table->type() == dd::enum_table_type::BASE_TABLE);
829
1/2
✓ Branch 0 taken 1909279 times.
✗ Branch 1 not taken.
1909281 open_table_err = open_table_def(
830
1/2
✓ Branch 0 taken 1909281 times.
✗ Branch 1 not taken.
1909281 thd, share, *dynamic_cast<const dd::Table *>(abstract_table));
831
832 /*
833 Update the table share with meta data from the schema object to
834 have it readily available to avoid performance degradation.
835 */
836
3/4
✓ Branch 0 taken 1909264 times.
✓ Branch 1 taken 15 times.
✓ Branch 2 taken 1909263 times.
✗ Branch 3 not taken.
1909279 if (!open_table_err) update_schema_options(sch, share);
837
838 /*
839 Read any existing histogram statistics from the data dictionary and
840 store a copy of them in the TABLE_SHARE.
841
842 We need to do this outside the protection of LOCK_open, since the data
843 dictionary might have to open tables in order to read histogram data
844 (such recursion will not work).
845 */
846
5/8
✓ Branch 0 taken 1909262 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 1909261 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1909261 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1909277 times.
1909278 if (!open_table_err && read_histograms(thd, share, sch, abstract_table))
847 open_table_err = true; /* purecov: deadcode */
848 }
849 2126227 }
850
851 /*
852 Get back LOCK_open before continuing. Notify all waiters that the
853 opening is finished, even if there was a failure while opening.
854 */
855
1/2
✓ Branch 0 taken 2126233 times.
✗ Branch 1 not taken.
2126233 mysql_mutex_lock(&LOCK_open);
856 2126233 share->m_open_in_progress = false;
857
1/2
✓ Branch 0 taken 2126233 times.
✗ Branch 1 not taken.
2126233 mysql_cond_broadcast(&COND_open);
858
859 /*
860 Fake an open_table_def error in debug build, resulting in
861 ER_NO_SUCH_TABLE.
862 */
863
4/6
✓ Branch 0 taken 2126233 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 2126231 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2126233 DBUG_EXECUTE_IF("set_open_table_err", {
864 open_table_err = true;
865 my_error(ER_NO_SUCH_TABLE, MYF(0), share->db.str, share->table_name.str);
866 });
867
868 /*
869 If there was an error while opening the definition, delete the
870 share from the TDC, and (implicitly) destroy the share. Waiters
871 will detect that the share is gone, and repeat the attempt at
872 opening the table definition. The ref counter must be stepped
873 down to allow the share to be destroyed.
874 */
875
2/2
✓ Branch 0 taken 25433 times.
✓ Branch 1 taken 2100800 times.
2126233 if (open_table_err) {
876 25433 share->error = true; // Allow waiters to detect the error
877
1/2
✓ Branch 0 taken 25433 times.
✗ Branch 1 not taken.
25433 share->decrement_ref_count();
878
2/4
✓ Branch 0 taken 25433 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25433 times.
✗ Branch 3 not taken.
25433 table_def_cache->erase(to_string(share->table_cache_key));
879 #if defined(ENABLED_DEBUG_SYNC)
880
3/4
✓ Branch 0 taken 25433 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25431 times.
✓ Branch 3 taken 2 times.
25433 if (!thd->is_attachable_ro_transaction_active())
881
3/4
✓ Branch 0 taken 21507 times.
✓ Branch 1 taken 3924 times.
✓ Branch 2 taken 21507 times.
✗ Branch 3 not taken.
25431 DEBUG_SYNC(thd, "get_share_after_destroy");
882 #endif
883 25433 return nullptr;
884 }
885
886 #ifdef HAVE_PSI_TABLE_INTERFACE
887 4201600 share->m_psi = PSI_TABLE_CALL(get_table_share)(
888
1/2
✓ Branch 0 taken 2100800 times.
✗ Branch 1 not taken.
2100800 (share->tmp_table != NO_TMP_TABLE), share);
889 #else
890 share->m_psi = NULL;
891 #endif
892
893
6/10
✓ Branch 0 taken 2100800 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2100800 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
✓ Branch 5 taken 2100746 times.
✓ Branch 6 taken 54 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 54 times.
✗ Branch 9 not taken.
2100800 DBUG_PRINT("exit", ("share: %p ref_count: %u", share, share->ref_count()));
894
895 /* If debug, assert that the share is actually present in the cache */
896 #ifndef NDEBUG
897
3/6
✓ Branch 0 taken 2100800 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2100800 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2100800 times.
2100800 assert(table_def_cache->count(string(key, key_length)) != 0);
898 #endif
899 2100800 return share;
900 4292072 }
901
902 /**
903 Get a table share. If it didn't exist, try creating it from engine
904
905 For arguments and return values, see get_table_share()
906 */
907
908 4290470 static TABLE_SHARE *get_table_share_with_discover(
909 THD *thd, TABLE_LIST *table_list, const char *key, size_t key_length,
910 bool open_secondary, int *error)
911
912 {
913 TABLE_SHARE *share;
914 bool exists;
915
1/2
✓ Branch 0 taken 4290470 times.
✗ Branch 1 not taken.
4290470 DBUG_TRACE;
916
917
1/2
✓ Branch 0 taken 4290467 times.
✗ Branch 1 not taken.
4290470 share = get_table_share(thd, table_list->db, table_list->table_name, key,
918 key_length, true, open_secondary);
919 /*
920 If share is not NULL, we found an existing share.
921
922 If share is NULL, and there is no error, we're inside
923 pre-locking, which silences 'ER_NO_SUCH_TABLE' errors
924 with the intention to silently drop non-existing tables
925 from the pre-locking list. In this case we still need to try
926 auto-discover before returning a NULL share.
927
928 Or, we're inside SHOW CREATE VIEW, which
929 also installs a silencer for ER_NO_SUCH_TABLE error.
930
931 If share is NULL and the error is ER_NO_SUCH_TABLE, this is
932 the same as above, only that the error was not silenced by
933 pre-locking or SHOW CREATE VIEW.
934
935 In both these cases it won't harm to try to discover the
936 table.
937
938 Finally, if share is still NULL, it's a real error and we need
939 to abort.
940
941 @todo Rework alternative ways to deal with ER_NO_SUCH TABLE.
942 */
943
9/10
✓ Branch 0 taken 25430 times.
✓ Branch 1 taken 4265037 times.
✓ Branch 2 taken 25430 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16963 times.
✓ Branch 5 taken 8467 times.
✓ Branch 6 taken 47 times.
✓ Branch 7 taken 16916 times.
✓ Branch 8 taken 4265084 times.
✓ Branch 9 taken 25383 times.
4307430 if (share || (thd->is_error() &&
944 16963 thd->get_stmt_da()->mysql_errno() != ER_NO_SUCH_TABLE)) {
945 4265084 return share;
946 }
947
948 25383 *error = 0;
949
950 /* Table didn't exist. Check if some engine can provide it */
951
2/4
✓ Branch 0 taken 25383 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 25383 times.
25383 if (ha_check_if_table_exists(thd, table_list->db, table_list->table_name,
952 &exists)) {
953 thd->clear_error();
954 thd->get_stmt_da()->reset_condition_info(thd);
955 /* Conventionally, the storage engine API does not report errors. */
956 my_error(ER_OUT_OF_RESOURCES, MYF(0));
957
1/2
✓ Branch 0 taken 25383 times.
✗ Branch 1 not taken.
25383 } else if (!exists) {
958 /*
959 No such table in any engine.
960 Hide "Table doesn't exist" errors if the table belongs to a view.
961 The check for thd->is_error() is necessary to not push an
962 unwanted error in case the error was already silenced.
963 @todo Rework the alternative ways to deal with ER_NO_SUCH TABLE.
964 */
965
3/4
✓ Branch 0 taken 25383 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16916 times.
✓ Branch 3 taken 8467 times.
25383 if (thd->is_error()) {
966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16916 times.
16916 if (table_list->parent_l) {
967 thd->clear_error();
968 thd->get_stmt_da()->reset_condition_info(thd);
969 my_error(ER_WRONG_MRG_TABLE, MYF(0));
970
2/2
✓ Branch 0 taken 284 times.
✓ Branch 1 taken 16632 times.
16916 } else if (table_list->belong_to_view) {
971 // Mention the top view in message, to not reveal underlying views.
972 284 TABLE_LIST *view = table_list->belong_to_view;
973
1/2
✓ Branch 0 taken 284 times.
✗ Branch 1 not taken.
284 thd->clear_error();
974
1/2
✓ Branch 0 taken 284 times.
✗ Branch 1 not taken.
284 thd->get_stmt_da()->reset_condition_info(thd);
975
1/2
✓ Branch 0 taken 284 times.
✗ Branch 1 not taken.
284 my_error(ER_VIEW_INVALID, MYF(0), view->db, view->table_name);
976 }
977 }
978 } else {
979 thd->clear_error();
980 thd->get_stmt_da()->reset_condition_info(thd);
981 *error = 7; /* Run auto-discover. */
982 }
983 25383 return nullptr;
984 4290467 }
985
986 /**
987 Mark that we are not using table share anymore.
988
989 @param share Table share
990
991 If the share has no open tables and (we have done a refresh or
992 if we have already too many open table shares) then delete the
993 definition.
994 */
995
996 4622885 void release_table_share(TABLE_SHARE *share) {
997
1/2
✓ Branch 0 taken 4622885 times.
✗ Branch 1 not taken.
4622885 DBUG_TRACE;
998
6/10
✓ Branch 0 taken 4622885 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4622885 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 107 times.
✓ Branch 5 taken 4622778 times.
✓ Branch 6 taken 107 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 107 times.
✗ Branch 9 not taken.
4622885 DBUG_PRINT("enter", ("share: %p table: %s.%s ref_count: %u version: %lu",
999 share, share->db.str, share->table_name.str,
1000 share->ref_count(), share->version()));
1001
1002 mysql_mutex_assert_owner(&LOCK_open);
1003
1004
2/4
✓ Branch 0 taken 4622885 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4622885 times.
4622885 assert(share->ref_count() != 0);
1005
3/4
✓ Branch 0 taken 4622885 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2603194 times.
✓ Branch 3 taken 2019691 times.
4622885 if (share->decrement_ref_count() == 0) {
1006
5/6
✓ Branch 0 taken 836027 times.
✓ Branch 1 taken 1767167 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 836027 times.
✓ Branch 4 taken 1767167 times.
✓ Branch 5 taken 836027 times.
2603194 if (share->has_old_version() || table_def_shutdown_in_progress)
1007
2/4
✓ Branch 0 taken 1767167 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1767167 times.
✗ Branch 3 not taken.
1767167 table_def_cache->erase(to_string(share->table_cache_key));
1008 else {
1009 /* Link share last in used_table_share list */
1010
5/8
✓ Branch 0 taken 836027 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 836027 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 36 times.
✓ Branch 5 taken 835991 times.
✓ Branch 6 taken 36 times.
✗ Branch 7 not taken.
836027 DBUG_PRINT("info", ("moving share to unused list"));
1011
1012
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 836027 times.
836027 assert(share->next == nullptr);
1013 836027 share->prev = end_of_unused_share.prev;
1014 836027 *end_of_unused_share.prev = share;
1015 836027 end_of_unused_share.prev = &share->next;
1016 836027 share->next = &end_of_unused_share;
1017
1018
2/2
✓ Branch 0 taken 720 times.
✓ Branch 1 taken 835307 times.
836027 if (table_def_cache->size() > table_def_size) {
1019 /* Delete the least used share to preserve LRU order. */
1020
2/4
✓ Branch 0 taken 720 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 720 times.
✗ Branch 3 not taken.
720 table_def_cache->erase(to_string(oldest_unused_share->table_cache_key));
1021 }
1022 }
1023 }
1024 4622885 }
1025
1026 /**
1027 Get an existing table definition from the table definition cache.
1028 */
1029
1030 602 TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) {
1031 char key[MAX_DBKEY_LENGTH];
1032 size_t key_length;
1033 mysql_mutex_assert_owner(&LOCK_open);
1034
1035
1/2
✓ Branch 0 taken 602 times.
✗ Branch 1 not taken.
602 key_length = create_table_def_key(db, table_name, key);
1036
2/4
✓ Branch 0 taken 602 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 602 times.
✗ Branch 3 not taken.
602 return find_or_nullptr(*table_def_cache, string(key, key_length));
1037 }
1038
1039 /*
1040 Create a list for all open tables matching SQL expression
1041
1042 SYNOPSIS
1043 list_open_tables()
1044 thd Thread THD
1045 wild SQL like expression
1046
1047 NOTES
1048 One gets only a list of tables for which one has any kind of privilege.
1049 db and table names are allocated in result struct, so one doesn't need
1050 a lock on LOCK_open when traversing the return list.
1051
1052 RETURN VALUES
1053 NULL Error (Probably OOM)
1054 # Pointer to list of names of open tables.
1055 */
1056
1057 68 OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) {
1058 OPEN_TABLE_LIST **start_list, *open_list, *start, *prev;
1059
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 TABLE_LIST table_list;
1060
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 DBUG_TRACE;
1061
1062 68 start_list = &open_list;
1063 68 open_list = nullptr;
1064
1065 /*
1066 This is done in two parts:
1067 1. First, we will make OPEN_TABLE_LIST under LOCK_open
1068 2. Second, we will check permission and unlink OPEN_TABLE_LIST
1069 entries if permission check fails
1070 */
1071
1072
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 table_cache_manager.lock_all_and_tdc();
1073
1074
2/2
✓ Branch 0 taken 3497 times.
✓ Branch 1 taken 68 times.
3565 for (const auto &key_and_value : *table_def_cache) {
1075 3497 TABLE_SHARE *share = key_and_value.second.get();
1076
1077 /* Skip shares that are being opened */
1078
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3495 times.
6035 if (share->m_open_in_progress) continue;
1079
7/8
✓ Branch 0 taken 2244 times.
✓ Branch 1 taken 1251 times.
✓ Branch 2 taken 2244 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2160 times.
✓ Branch 5 taken 84 times.
✓ Branch 6 taken 2160 times.
✓ Branch 7 taken 1335 times.
3495 if (db && my_strcasecmp(system_charset_info, db, share->db.str)) continue;
1080
6/6
✓ Branch 0 taken 403 times.
✓ Branch 1 taken 932 times.
✓ Branch 2 taken 378 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 378 times.
✓ Branch 5 taken 957 times.
1738 if (wild && wild_compare(share->table_name.str, share->table_name.length,
1081
1/2
✓ Branch 0 taken 403 times.
✗ Branch 1 not taken.
403 wild, strlen(wild), false))
1082 378 continue;
1083
1084
1/2
✓ Branch 0 taken 957 times.
✗ Branch 1 not taken.
957 if (!(*start_list = (OPEN_TABLE_LIST *)(*THR_MALLOC)
1085
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 957 times.
957 ->Alloc(sizeof(**start_list) +
1086
1/2
✓ Branch 0 taken 957 times.
✗ Branch 1 not taken.
957 share->table_cache_key.length))) {
1087 open_list = nullptr; // Out of memory
1088 break;
1089 }
1090 1914 my_stpcpy((*start_list)->table =
1091 957 my_stpcpy(((*start_list)->db = (char *)((*start_list) + 1)),
1092 957 share->db.str) +
1093 1,
1094 share->table_name.str);
1095 957 (*start_list)->in_use = 0;
1096
1/2
✓ Branch 0 taken 957 times.
✗ Branch 1 not taken.
957 Table_cache_iterator it(share);
1097
3/4
✓ Branch 0 taken 975 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 957 times.
975 while (it++) ++(*start_list)->in_use;
1098 957 (*start_list)->locked = 0; /* Obsolete. */
1099 957 start_list = &(*start_list)->next;
1100 957 *start_list = nullptr;
1101 }
1102
1/2
✓ Branch 0 taken 68 times.
✗ Branch 1 not taken.
68 table_cache_manager.unlock_all_and_tdc();
1103
1104 68 start = open_list;
1105 68 prev = start;
1106
1107
2/2
✓ Branch 0 taken 957 times.
✓ Branch 1 taken 68 times.
1025 while (start) {
1108 /* Check if user has SELECT privilege for any column in the table */
1109 957 table_list.db = start->db;
1110 957 table_list.table_name = start->table;
1111 957 table_list.grant.privilege = 0;
1112
1113
2/4
✓ Branch 0 taken 957 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 957 times.
957 if (check_table_access(thd, SELECT_ACL, &table_list, true, 1, true)) {
1114 /* Unlink OPEN_TABLE_LIST */
1115 if (start == open_list) {
1116 open_list = start->next;
1117 prev = open_list;
1118 } else
1119 prev->next = start->next;
1120 } else
1121 957 prev = start;
1122 957 start = start->next;
1123 }
1124
1125 68 return open_list;
1126 68 }
1127
1128 /*****************************************************************************
1129 * Functions to free open table cache
1130 ****************************************************************************/
1131
1132 4045545 void intern_close_table(TABLE *table) { // Free all structures
1133
1/2
✓ Branch 0 taken 4045545 times.
✗ Branch 1 not taken.
4045545 DBUG_TRACE;
1134
7/12
✓ Branch 0 taken 4045545 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4045545 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 82 times.
✓ Branch 5 taken 4045463 times.
✓ Branch 6 taken 82 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 82 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 82 times.
✗ Branch 11 not taken.
4045545 DBUG_PRINT("tcache",
1135 ("table: '%s'.'%s' %p", table->s ? table->s->db.str : "?",
1136 table->s ? table->s->table_name.str : "?", table));
1137
1138
1/2
✓ Branch 0 taken 4045545 times.
✗ Branch 1 not taken.
4045545 free_io_cache(table);
1139 4045545 destroy(table->triggers);
1140
1/2
✓ Branch 0 taken 4045545 times.
✗ Branch 1 not taken.
4045545 if (table->file) // Not true if placeholder
1141
1/2
✓ Branch 0 taken 4045545 times.
✗ Branch 1 not taken.
4045545 (void)closefrm(table, true); // close file
1142 4045545 destroy(table);
1143
1/2
✓ Branch 0 taken 4045545 times.
✗ Branch 1 not taken.
4045545 my_free(table);
1144 4045545 }
1145
1146 /* Free resources allocated by filesort() and read_record() */
1147
1148 127097240 void free_io_cache(TABLE *table) {
1149
1/2
✓ Branch 0 taken 127098902 times.
✗ Branch 1 not taken.
127097240 DBUG_TRACE;
1150
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127098902 times.
127098902 if (table->unique_result.io_cache) {
1151 close_cached_file(table->unique_result.io_cache);
1152 my_free(table->unique_result.io_cache);
1153 table->unique_result.io_cache = nullptr;
1154 }
1155 127098902 }
1156
1157 /*
1158 Close all tables which aren't in use by any thread
1159
1160 @param thd Thread context
1161 @param tables List of tables to remove from the cache
1162 @param wait_for_refresh Wait for a impending flush
1163 @param timeout Timeout for waiting for flush to be completed.
1164
1165 @note THD can be NULL, but then wait_for_refresh must be false
1166 and tables must be NULL.
1167
1168 @note When called as part of FLUSH TABLES WITH READ LOCK this function
1169 ignores metadata locks held by other threads. In order to avoid
1170 situation when FLUSH TABLES WITH READ LOCK sneaks in at the moment
1171 when some write-locked table is being reopened (by FLUSH TABLES or
1172 ALTER TABLE) we have to rely on additional global shared metadata
1173 lock taken by thread trying to obtain global read lock.
1174 */
1175
1176 40361 bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool wait_for_refresh,
1177 ulong timeout) {
1178 40361 bool result = false;
1179 40361 bool found = true;
1180 struct timespec abstime;
1181
1/2
✓ Branch 0 taken 40361 times.
✗ Branch 1 not taken.
40361 DBUG_TRACE;
1182
4/6
✓ Branch 0 taken 18083 times.
✓ Branch 1 taken 22278 times.
✓ Branch 2 taken 18083 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 18083 times.
✗ Branch 5 not taken.
40361 assert(thd || (!wait_for_refresh && !tables));
1183
1184
1/2
✓ Branch 0 taken 40361 times.
✗ Branch 1 not taken.
40361 table_cache_manager.lock_all_and_tdc();
1185
2/2
✓ Branch 0 taken 40064 times.
✓ Branch 1 taken 297 times.
40361 if (!tables) {
1186 /*
1187 Force close of all open tables.
1188
1189 Note that code in TABLE_SHARE::wait_for_old_version() assumes that
1190 incrementing of refresh_version and removal of unused tables and
1191 shares from TDC happens atomically under protection of LOCK_open,
1192 or putting it another way that TDC does not contain old shares
1193 which don't have any tables used.
1194 */
1195 40064 refresh_version++;
1196
3/8
✓ Branch 0 taken 40064 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 40064 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40064 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
40064 DBUG_PRINT("tcache",
1197 ("incremented global refresh_version to: %lu", refresh_version));
1198
1199 /*
1200 Get rid of all unused TABLE and TABLE_SHARE instances. By doing
1201 this we automatically close all tables which were marked as "old".
1202 */
1203
1/2
✓ Branch 0 taken 40064 times.
✗ Branch 1 not taken.
40064 table_cache_manager.free_all_unused_tables();
1204 /* Free table shares which were not freed implicitly by loop above. */
1205
2/2
✓ Branch 0 taken 173266 times.
✓ Branch 1 taken 40064 times.
213330 while (oldest_unused_share->next)
1206
2/4
✓ Branch 0 taken 173266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 173266 times.
✗ Branch 3 not taken.
173266 table_def_cache->erase(to_string(oldest_unused_share->table_cache_key));
1207 } else {
1208 297 bool share_found = false;
1209
2/2
✓ Branch 0 taken 308 times.
✓ Branch 1 taken 297 times.
605 for (TABLE_LIST *table = tables; table; table = table->next_local) {
1210
1/2
✓ Branch 0 taken 308 times.
✗ Branch 1 not taken.
308 TABLE_SHARE *share = get_cached_table_share(table->db, table->table_name);
1211
1212
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 34 times.
308 if (share) {
1213 /*
1214 tdc_remove_table() also sets TABLE_SHARE::version to 0. Note that
1215 it will work correctly even if m_open_in_progress flag is true.
1216 */
1217
1/2
✓ Branch 0 taken 274 times.
✗ Branch 1 not taken.
274 tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
1218 table->table_name, true);
1219 274 share_found = true;
1220 }
1221 }
1222
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 266 times.
297 if (!share_found) wait_for_refresh = false; // Nothing to wait for
1223 }
1224
1225
1/2
✓ Branch 0 taken 40361 times.
✗ Branch 1 not taken.
40361 table_cache_manager.unlock_all_and_tdc();
1226
1227
2/2
✓ Branch 0 taken 18201 times.
✓ Branch 1 taken 22160 times.
40361 if (!wait_for_refresh) return result;
1228
1229
1/2
✓ Branch 0 taken 22160 times.
✗ Branch 1 not taken.
22160 set_timespec(&abstime, timeout);
1230
1231
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 22129 times.
22160 if (thd->locked_tables_mode) {
1232 /*
1233 If we are under LOCK TABLES, we need to reopen the tables without
1234 opening a door for any concurrent threads to sneak in and get
1235 lock on our tables. To achieve this we use exclusive metadata
1236 locks.
1237 */
1238 TABLE_LIST *tables_to_reopen =
1239
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 26 times.
31 (tables ? tables : thd->locked_tables_list.locked_tables());
1240
1241 /* Close open HANLER instances to avoid self-deadlock. */
1242
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 mysql_ha_flush_tables(thd, tables_to_reopen);
1243
1244
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 31 times.
64 for (TABLE_LIST *table_list = tables_to_reopen; table_list;
1245 33 table_list = table_list->next_global) {
1246 /* A check that the table was locked for write is done by the caller. */
1247
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 TABLE *table = find_table_for_mdl_upgrade(thd, table_list->db,
1248 table_list->table_name, true);
1249
1250 /* May return NULL if this table has already been closed via an alias. */
1251
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (!table) continue;
1252
1253
2/4
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 33 times.
33 if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN)) {
1254 result = true;
1255 goto err_with_reopen;
1256 }
1257
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 close_all_tables_for_name(thd, table->s, false, nullptr);
1258 }
1259 }
1260
1261 /* Wait until all threads have closed all the tables we are flushing. */
1262
3/8
✓ Branch 0 taken 22160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22160 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 22160 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
22160 DBUG_PRINT("info", ("Waiting for other threads to close their open tables"));
1263
1264
6/6
✓ Branch 0 taken 22246 times.
✓ Branch 1 taken 22157 times.
✓ Branch 2 taken 22243 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 22243 times.
✓ Branch 5 taken 22160 times.
44403 while (found && !thd->killed) {
1265 22243 TABLE_SHARE *share = nullptr;
1266 22243 found = false;
1267 /*
1268 To a self-deadlock or deadlocks with other FLUSH threads
1269 waiting on our open HANDLERs, we have to flush them.
1270 */
1271
1/2
✓ Branch 0 taken 22243 times.
✗ Branch 1 not taken.
22243 mysql_ha_flush(thd);
1272
3/4
✓ Branch 0 taken 21737 times.
✓ Branch 1 taken 506 times.
✓ Branch 2 taken 21737 times.
✗ Branch 3 not taken.
22243 DEBUG_SYNC(thd, "after_flush_unlock");
1273
1274
1/2
✓ Branch 0 taken 22243 times.
✗ Branch 1 not taken.
22243 mysql_mutex_lock(&LOCK_open);
1275
1276
2/2
✓ Branch 0 taken 21980 times.
✓ Branch 1 taken 263 times.
22243 if (!tables) {
1277
2/2
✓ Branch 0 taken 194 times.
✓ Branch 1 taken 21897 times.
22091 for (const auto &key_and_value : *table_def_cache) {
1278 194 share = key_and_value.second.get();
1279
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 111 times.
194 if (share->has_old_version()) {
1280 83 found = true;
1281 83 break;
1282 }
1283 }
1284 } else {
1285
2/2
✓ Branch 0 taken 270 times.
✓ Branch 1 taken 260 times.
530 for (TABLE_LIST *table = tables; table; table = table->next_local) {
1286
1/2
✓ Branch 0 taken 270 times.
✗ Branch 1 not taken.
270 share = get_cached_table_share(table->db, table->table_name);
1287
6/6
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 266 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 267 times.
270 if (share && share->has_old_version()) {
1288 3 found = true;
1289 3 break;
1290 }
1291 }
1292 }
1293
1294
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 22157 times.
22243 if (found) {
1295 /*
1296 The method below temporarily unlocks LOCK_open and frees
1297 share's memory. Note that it works correctly even for
1298 shares with m_open_in_progress flag set.
1299 */
1300
2/4
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 86 times.
86 if (share->wait_for_old_version(
1301 thd, &abstime, MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DDL)) {
1302 mysql_mutex_unlock(&LOCK_open);
1303 result = true;
1304 goto err_with_reopen;
1305 }
1306 }
1307
1308
1/2
✓ Branch 0 taken 22243 times.
✗ Branch 1 not taken.
22243 mysql_mutex_unlock(&LOCK_open);
1309 }
1310
1311 22160 err_with_reopen:
1312
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 22129 times.
22160 if (thd->locked_tables_mode) {
1313 /*
1314 No other thread has the locked tables open; reopen them and get the
1315 old locks. This should succeed unless any dictionary operations fail
1316 (e.g. when opening a dictionary table on cache miss).
1317 */
1318
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 result |= thd->locked_tables_list.reopen_tables(thd);
1319 /*
1320 Since downgrade_lock() won't do anything with shared
1321 metadata lock it is much simpler to go through all open tables rather
1322 than picking only those tables that were flushed.
1323 */
1324
2/2
✓ Branch 0 taken 46 times.
✓ Branch 1 taken 31 times.
77 for (TABLE *tab = thd->open_tables; tab; tab = tab->next)
1325
1/2
✓ Branch 0 taken 46 times.
✗ Branch 1 not taken.
46 tab->mdl_ticket->downgrade_lock(MDL_SHARED_NO_READ_WRITE);
1326 }
1327
3/4
✓ Branch 0 taken 22160 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 22157 times.
22160 return result || thd->killed;
1328 40361 }
1329
1330 /**
1331 Mark all temporary tables which were used by the current statement or
1332 substatement as free for reuse, but only if the query_id can be cleared.
1333
1334 @param thd thread context
1335
1336 @remark For temp tables associated with a open SQL HANDLER the query_id
1337 is not reset until the HANDLER is closed.
1338 */
1339
1340 54210843 static void mark_temp_tables_as_free_for_reuse(THD *thd) {
1341
2/2
✓ Branch 0 taken 3629122 times.
✓ Branch 1 taken 54210850 times.
57839972 for (TABLE *table = thd->temporary_tables; table; table = table->next) {
1342
4/4
✓ Branch 0 taken 244435 times.
✓ Branch 1 taken 3384687 times.
✓ Branch 2 taken 244408 times.
✓ Branch 3 taken 27 times.
3629122 if ((table->query_id == thd->query_id) && !table->open_by_handler) {
1343 244408 mark_tmp_table_for_reuse(table);
1344 244407 table->cleanup_value_generator_items();
1345 244404 table->cleanup_partial_update();
1346 }
1347 }
1348 54210850 }
1349
1350 /**
1351 Reset a single temporary table.
1352 Effectively this "closes" one temporary table,
1353 in a session.
1354
1355 @param table Temporary table.
1356 */
1357
1358 244433 void mark_tmp_table_for_reuse(TABLE *table) {
1359
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 244433 times.
244433 assert(table->s->tmp_table);
1360
1361 244433 table->query_id = 0;
1362 244433 table->file->ha_reset();
1363
1364 /* Detach temporary MERGE children from temporary parent. */
1365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 244437 times.
244437 assert(table->file);
1366 244437 table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
1367
1368 /*
1369 Reset temporary table lock type to it's default value (TL_WRITE).
1370
1371 Statements such as INSERT INTO .. SELECT FROM tmp, CREATE TABLE
1372 .. SELECT FROM tmp and UPDATE may under some circumstances modify
1373 the lock type of the tables participating in the statement. This
1374 isn't a problem for non-temporary tables since their lock type is
1375 reset at every open, but the same does not occur for temporary
1376 tables for historical reasons.
1377
1378 Furthermore, the lock type of temporary tables is not really that
1379 important because they can only be used by one query at a time and
1380 not even twice in a query -- a temporary table is represented by
1381 only one TABLE object. Nonetheless, it's safer from a maintenance
1382 point of view to reset the lock type of this singleton TABLE object
1383 as to not cause problems when the table is reused.
1384
1385 Even under LOCK TABLES mode its okay to reset the lock type as
1386 LOCK TABLES is allowed (but ignored) for a temporary table.
1387 */
1388 244435 table->reginfo.lock_type = TL_WRITE;
1389 244435 }
1390
1391 /*
1392 Mark all tables in the list which were used by current substatement
1393 as free for reuse.
1394
1395 SYNOPSIS
1396 mark_used_tables_as_free_for_reuse()
1397 thd - thread context
1398 table - head of the list of tables
1399
1400 DESCRIPTION
1401 Marks all tables in the list which were used by current substatement
1402 (they are marked by its query_id) as free for reuse.
1403
1404 NOTE
1405 The reason we reset query_id is that it's not enough to just test
1406 if table->query_id != thd->query_id to know if a table is in use.
1407
1408 For example
1409 SELECT f1_that_uses_t1() FROM t1;
1410 In f1_that_uses_t1() we will see one instance of t1 where query_id is
1411 set to query_id of original query.
1412 */
1413
1414 2867379 static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table) {
1415
2/2
✓ Branch 0 taken 7860872 times.
✓ Branch 1 taken 2867379 times.
10728251 for (; table; table = table->next) {
1416
3/4
✓ Branch 0 taken 4800837 times.
✓ Branch 1 taken 3060035 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4800837 times.
7860872 assert(table->pos_in_locked_tables == nullptr ||
1417 table->pos_in_locked_tables->table == table);
1418
2/2
✓ Branch 0 taken 2074799 times.
✓ Branch 1 taken 5786073 times.
7860872 if (table->query_id == thd->query_id) {
1419 2074799 table->query_id = 0;
1420 2074799 table->file->ha_reset();
1421 }
1422 }
1423 2867379 }
1424
1425 /**
1426 Auxiliary function to close all tables in the open_tables list.
1427
1428 @param thd Thread context.
1429
1430 @remark It should not ordinarily be called directly.
1431 */
1432
1433 32325219 static void close_open_tables(THD *thd) {
1434 mysql_mutex_assert_not_owner(&LOCK_open);
1435
1436
2/2
✓ Branch 0 taken 1436 times.
✓ Branch 1 taken 32325024 times.
32325219 DBUG_PRINT("info", ("thd->open_tables: %p", thd->open_tables));
1437
1438
2/2
✓ Branch 0 taken 106372553 times.
✓ Branch 1 taken 32327111 times.
138699045 while (thd->open_tables) close_thread_table(thd, &thd->open_tables);
1439 32327111 }
1440
1441 /**
1442 Close all open instances of the table but keep the MDL lock.
1443
1444 Works both under LOCK TABLES and in the normal mode.
1445 Removes all closed instances of the table from the table cache.
1446
1447 @param thd Thread context.
1448 @param key TC/TDC key identifying the table.
1449 @param key_length Length of TC/TDC key identifying the table.
1450 @param db Database name.
1451 @param table_name Table name.
1452 @param remove_from_locked_tables
1453 True if the table is being dropped.
1454 In that case the documented behaviour is to
1455 implicitly remove the table from LOCK TABLES list.
1456 @param skip_table TABLE instance that should be kept open.
1457
1458 @pre Must be called with an X MDL lock on the table.
1459 */
1460 525054 static void close_all_tables_for_name(THD *thd, const char *key,
1461 size_t key_length, const char *db,
1462 const char *table_name,
1463 bool remove_from_locked_tables,
1464 TABLE *skip_table) {
1465 mysql_mutex_assert_not_owner(&LOCK_open);
1466
2/2
✓ Branch 0 taken 123136 times.
✓ Branch 1 taken 525054 times.
648190 for (TABLE **prev = &thd->open_tables; *prev;) {
1467 123136 TABLE *table = *prev;
1468
1469
2/2
✓ Branch 0 taken 122931 times.
✓ Branch 1 taken 205 times.
123136 if (table->s->table_cache_key.length == key_length &&
1470
4/4
✓ Branch 0 taken 122695 times.
✓ Branch 1 taken 236 times.
✓ Branch 2 taken 116606 times.
✓ Branch 3 taken 6089 times.
122931 !memcmp(table->s->table_cache_key.str, key, key_length) &&
1471 table != skip_table) {
1472 116606 thd->locked_tables_list.unlink_from_list(thd, table->pos_in_locked_tables,
1473 remove_from_locked_tables);
1474 /*
1475 Does nothing if the table is not locked.
1476 This allows one to use this function after a table
1477 has been unlocked, e.g. in partition management.
1478 */
1479 116606 mysql_lock_remove(thd, thd->lock, table);
1480
1481 /* Inform handler that table will be dropped after close */
1482
3/4
✓ Branch 0 taken 116606 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 116599 times.
✓ Branch 3 taken 7 times.
116606 if (table->db_stat && /* Not true for partitioned tables. */
1483 skip_table == nullptr)
1484 116599 table->file->ha_extra(HA_EXTRA_PREPARE_FOR_DROP);
1485 116606 close_thread_table(thd, prev);
1486 } else {
1487 /* Step to next entry in open_tables list. */
1488 6530 prev = &table->next;
1489 }
1490 }
1491
2/2
✓ Branch 0 taken 518965 times.
✓ Branch 1 taken 6089 times.
525054 if (skip_table == nullptr) {
1492 /* Remove the table share from the cache. */
1493 518965 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, db, table_name, false);
1494 }
1495 525054 }
1496
1497 122579 void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
1498 bool remove_from_locked_tables,
1499 TABLE *skip_table) {
1500 char key[MAX_DBKEY_LENGTH];
1501 122579 size_t key_length = share->table_cache_key.length;
1502
1503 122579 memcpy(key, share->table_cache_key.str, key_length);
1504
1505 122579 close_all_tables_for_name(thd, key, key_length,
1506 key, // db
1507
1/2
✓ Branch 0 taken 122579 times.
✗ Branch 1 not taken.
122579 key + share->db.length + 1, // table_name
1508 remove_from_locked_tables, skip_table);
1509 122579 }
1510
1511 402475 void close_all_tables_for_name(THD *thd, const char *db, const char *table_name,
1512 bool remove_from_locked_tables) {
1513 char key[MAX_DBKEY_LENGTH];
1514
1/2
✓ Branch 0 taken 402475 times.
✗ Branch 1 not taken.
402475 size_t key_length = create_table_def_key(db, table_name, key);
1515
1516
1/2
✓ Branch 0 taken 402475 times.
✗ Branch 1 not taken.
402475 close_all_tables_for_name(thd, key, key_length, db, table_name,
1517 remove_from_locked_tables, nullptr);
1518 402475 }
1519
1520 // Check if we are under LOCK TABLE mode, and not prelocking.
1521 109792105 static inline bool in_LTM(THD *thd) {
1522
2/2
✓ Branch 0 taken 109555306 times.
✓ Branch 1 taken 236799 times.
219347411 return (thd->locked_tables_mode == LTM_LOCK_TABLES ||
1523
2/2
✓ Branch 0 taken 712 times.
✓ Branch 1 taken 109554594 times.
219347411 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES);
1524 }
1525
1526 /**
1527 Check if the given TABLE_LIST belongs to a DD table.
1528
1529 The function checks whether the table is a DD table being used in the
1530 context of a DD transaction, or whether it is referred by a system view.
1531 Then, it implies that if either of these two conditions hold, then this
1532 is a DD table. If in case this is a DD table being used in some other
1533 situation, then this function does not return 'true'. We do not know if
1534 there is such a situation right now.
1535
1536 This function ignores TABLE_LIST's that is created by optimizer
1537 when processing a system view.
1538
1539 @param tl TABLE_LIST point to the table.
1540
1541 @retval true If table belongs to a DD table.
1542 @retval false If table does not.
1543 */
1544 107730693 static bool belongs_to_dd_table(const TABLE_LIST *tl) {
1545
2/2
✓ Branch 0 taken 16902543 times.
✓ Branch 1 taken 90828150 times.
124633553 return (tl->is_dd_ctx_table ||
1546
4/4
✓ Branch 0 taken 16902875 times.
✓ Branch 1 taken 715 times.
✓ Branch 2 taken 16902066 times.
✓ Branch 3 taken 79 times.
16902543 (!tl->is_internal() && !tl->uses_materialization() &&
1547
4/4
✓ Branch 0 taken 2869629 times.
✓ Branch 1 taken 14032437 times.
✓ Branch 2 taken 2627108 times.
✓ Branch 3 taken 242521 times.
124633076 tl->referencing_view && tl->referencing_view->is_system_view));
1548 }
1549
1550 /**
1551 Close all tables used by the current substatement, or all tables
1552 used by this thread if we are on the outer-most level.
1553
1554 @param thd Thread handler
1555
1556 @details
1557 Unlocks all open persistent and temporary base tables.
1558 Put all persistent base tables used by thread in free list.
1559
1560 It will only close/mark as free for reuse tables opened by this
1561 substatement, it will also check if we are closing tables after
1562 execution of complete query (i.e. we are on outer-most level) and will
1563 leave prelocked mode if needed.
1564 */
1565
1566 54208084 void close_thread_tables(THD *thd) {
1567
1/2
✓ Branch 0 taken 54212316 times.
✗ Branch 1 not taken.
54208084 DBUG_TRACE;
1568
1569 #ifdef EXTRA_DEBUG
1570 DBUG_PRINT("tcache", ("open tables:"));
1571 for (TABLE *table = thd->open_tables; table; table = table->next)
1572 DBUG_PRINT("tcache", ("table: '%s'.'%s' %p", table->s->db.str,
1573 table->s->table_name.str, table));
1574 #endif
1575
1576 #if defined(ENABLED_DEBUG_SYNC)
1577 /* debug_sync may not be initialized for some slave threads */
1578
4/6
✓ Branch 0 taken 50835716 times.
✓ Branch 1 taken 3376600 times.
✓ Branch 2 taken 50835201 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 50836151 times.
✗ Branch 5 not taken.
54212316 if (thd->debug_sync_control) DEBUG_SYNC(thd, "before_close_thread_tables");
1579 #endif
1580
1581 // TODO: dd::Transaction_impl::end() does merge DD transaction into
1582 // thd->transaction.stmt. Later the can be second DD transaction
1583 // which would call close_thread_tables(). In this case, the
1584 // condition thd->transaction.stmt.is_empty() does not hold good.
1585 // So we comment this assert for now.
1586 //
1587 // We should consider retaining this assert if we plan to commit
1588 // DD RW transaction just before next close_thread_tables().
1589 // We are not sure if this is doable and needs to be explored.
1590 // Alik and myself plan to comment this assert for now temporarily
1591 // and address this TODO asap.
1592 //
1593 // assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
1594 // thd->in_sub_stmt ||
1595 // (thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
1596
1597 /* Detach MERGE children after every statement. Even under LOCK TABLES. */
1598
2/2
✓ Branch 0 taken 112265634 times.
✓ Branch 1 taken 54213415 times.
166479049 for (TABLE *table = thd->open_tables; table; table = table->next) {
1599 /* Table might be in use by some outer statement. */
1600
5/8
✓ Branch 0 taken 112265711 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 112265829 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6374 times.
✓ Branch 5 taken 112259455 times.
✓ Branch 6 taken 6374 times.
✗ Branch 7 not taken.
112265634 DBUG_PRINT("tcache", ("table: '%s' query_id: %lu",
1601 table->s->table_name.str, (ulong)table->query_id));
1602
2/2
✓ Branch 0 taken 3060978 times.
✓ Branch 1 taken 109204851 times.
112265829 if (thd->locked_tables_mode <= LTM_LOCK_TABLES ||
1603
2/2
✓ Branch 0 taken 2070821 times.
✓ Branch 1 taken 990157 times.
3060978 table->query_id == thd->query_id) {
1604
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 111275672 times.
111275672 assert(table->file);
1605
3/4
✓ Branch 0 taken 111114954 times.
✓ Branch 1 taken 160718 times.
✓ Branch 2 taken 111114096 times.
✗ Branch 3 not taken.
111275672 if (table->db_stat) table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
1606
1/2
✓ Branch 0 taken 111274995 times.
✗ Branch 1 not taken.
111274814 table->cleanup_value_generator_items();
1607
1/2
✓ Branch 0 taken 111276303 times.
✗ Branch 1 not taken.
111274995 table->cleanup_partial_update();
1608 }
1609 }
1610
1611 /*
1612 Mark all temporary tables used by this statement as free for reuse.
1613 */
1614
1/2
✓ Branch 0 taken 54211052 times.
✗ Branch 1 not taken.
54213415 mark_temp_tables_as_free_for_reuse(thd);
1615
1616
2/2
✓ Branch 0 taken 2867379 times.
✓ Branch 1 taken 51343673 times.
54211052 if (thd->locked_tables_mode) {
1617 /*
1618 If we have
1619 1) Implicitly opened some DD tables that belong to IS system
1620 view executed in LOCK TABLE mode, then we should close them now.
1621 2) Close P_S tables opened implicitly under LOCK TABLE mode.
1622 */
1623
2/2
✓ Branch 0 taken 46781 times.
✓ Branch 1 taken 2820598 times.
2867379 if (in_LTM(thd)) {
1624
2/2
✓ Branch 0 taken 4875900 times.
✓ Branch 1 taken 46781 times.
4922681 for (TABLE **prev = &thd->open_tables; *prev;) {
1625 4875900 TABLE *table = *prev;
1626
1627 /* Ignore tables locked explicitly by LOCK TABLE. */
1628
2/2
✓ Branch 0 taken 75063 times.
✓ Branch 1 taken 4800837 times.
4875900 if (!table->pos_in_locked_tables) {
1629 /*
1630 We close tables only when all of following conditions satisfy,
1631 - The table is not locked explicitly by user using LOCK TABLE
1632 command.
1633 - We are not executing a IS queries as part of SF/Trigger.
1634 - The table belongs to a new DD table.
1635 OR
1636 - Close P_S tables unless the query is inside of a SP/trigger.
1637 */
1638 75063 TABLE_LIST *tbl_list = table->pos_in_table_list;
1639
7/8
✓ Branch 0 taken 74889 times.
✓ Branch 1 taken 174 times.
✓ Branch 2 taken 823 times.
✓ Branch 3 taken 74066 times.
✓ Branch 4 taken 823 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 74889 times.
✓ Branch 7 taken 174 times.
75886 if (!thd->in_sub_stmt && (belongs_to_dd_table(tbl_list) ||
1640 823 belongs_to_p_s(table->pos_in_table_list))) {
1641
1/2
✓ Branch 0 taken 74889 times.
✗ Branch 1 not taken.
74889 if (!table->s->tmp_table) {
1642
1/2
✓ Branch 0 taken 74889 times.
✗ Branch 1 not taken.
74889 table->file->ha_index_or_rnd_end();
1643
1/2
✓ Branch 0 taken 74889 times.
✗ Branch 1 not taken.
74889 table->set_keyread(false);
1644 74889 table->open_by_handler = false;
1645 /*
1646 In case we have opened the DD table but the statement
1647 fails before calling ha_external_lock() requesting
1648 read lock in open_tables(), then we need to check
1649 if we have really requested lock and then unlock.
1650 */
1651
2/2
✓ Branch 0 taken 74690 times.
✓ Branch 1 taken 199 times.
74889 if (table->file->get_lock_type() != F_UNLCK)
1652
1/2
✓ Branch 0 taken 74690 times.
✗ Branch 1 not taken.
74690 table->file->ha_external_lock(thd, F_UNLCK);
1653
1/2
✓ Branch 0 taken 74889 times.
✗ Branch 1 not taken.
74889 close_thread_table(thd, prev);
1654 74889 continue;
1655 }
1656 }
1657 }
1658 4801011 prev = &table->next;
1659 } // End of for
1660 }
1661
1662 /* Ensure we are calling ha_reset() for all used tables */
1663
1/2
✓ Branch 0 taken 2867379 times.
✗ Branch 1 not taken.
2867379 mark_used_tables_as_free_for_reuse(thd, thd->open_tables);
1664
1665 /*
1666 Mark this statement as one that has "unlocked" its tables.
1667 For purposes of Query_tables_list::lock_tables_state we treat
1668 any statement which passed through close_thread_tables() as
1669 such.
1670 */
1671 2867379 thd->lex->lock_tables_state = Query_tables_list::LTS_NOT_LOCKED;
1672
1673 /*
1674 We are under simple LOCK TABLES or we're inside a sub-statement
1675 of a prelocked statement, so should not do anything else.
1676
1677 Note that even if we are in LTM_LOCK_TABLES mode and statement
1678 requires prelocking (e.g. when we are closing tables after
1679 failing to "open" all tables required for statement execution)
1680 we will exit this function a few lines below.
1681 */
1682
2/2
✓ Branch 0 taken 842874 times.
✓ Branch 1 taken 2024505 times.
2867379 if (!thd->lex->requires_prelocking()) return;
1683
1684 /*
1685 We are in the top-level statement of a prelocked statement,
1686 so we have to leave the prelocked mode now with doing implicit
1687 UNLOCK TABLES if needed.
1688 */
1689
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 2024435 times.
2024505 if (thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
1690 70 thd->locked_tables_mode = LTM_LOCK_TABLES;
1691
1692
2/2
✓ Branch 0 taken 239 times.
✓ Branch 1 taken 2024266 times.
2024505 if (thd->locked_tables_mode == LTM_LOCK_TABLES) return;
1693
1694
1/2
✓ Branch 0 taken 2024266 times.
✗ Branch 1 not taken.
2024266 thd->leave_locked_tables_mode();
1695
1696 /* Fallthrough */
1697 }
1698
1699
2/2
✓ Branch 0 taken 32507209 times.
✓ Branch 1 taken 20860730 times.
53367939 if (thd->lock) {
1700 /*
1701 For RBR we flush the pending event just before we unlock all the
1702 tables. This means that we are at the end of a topmost
1703 statement, so we ensure that the STMT_END_F flag is set on the
1704 pending event. For statements that are *inside* stored
1705 functions, the pending event will not be flushed: that will be
1706 handled either before writing a query log event (inside
1707 binlog_query()) or when preparing a pending event.
1708 */
1709
1/2
✓ Branch 0 taken 32507718 times.
✗ Branch 1 not taken.
32507209 (void)thd->binlog_flush_pending_rows_event(true);
1710
1/2
✓ Branch 0 taken 32508541 times.
✗ Branch 1 not taken.
32507718 mysql_unlock_tables(thd, thd->lock);
1711 32508541 thd->lock = nullptr;
1712 }
1713
1714 53369271 thd->lex->lock_tables_state = Query_tables_list::LTS_NOT_LOCKED;
1715
1716 /*
1717 Closing a MERGE child before the parent would be fatal if the
1718 other thread tries to abort the MERGE lock in between.
1719 */
1720
3/4
✓ Branch 0 taken 32326830 times.
✓ Branch 1 taken 21042441 times.
✓ Branch 2 taken 32325558 times.
✗ Branch 3 not taken.
53369271 if (thd->open_tables) close_open_tables(thd);
1721
2/2
✓ Branch 0 taken 53369549 times.
✓ Branch 1 taken 843095 times.
54211112 }
1722
1723 /**
1724 Helper function which returns TABLE to Table Cache or closes if
1725 table is marked as needing re-open.
1726 */
1727 106649374 static void release_or_close_table(THD *thd, TABLE *table) {
1728 106649374 Table_cache *tc = table_cache_manager.get_cache(thd);
1729
1730 106650020 tc->lock();
1731
1732
2/2
✓ Branch 0 taken 106310614 times.
✓ Branch 1 taken 224400 times.
213184512 if (table->s->has_old_version() || table->has_invalid_dict() ||
1733
8/8
✓ Branch 0 taken 106534817 times.
✓ Branch 1 taken 115251 times.
✓ Branch 2 taken 106308607 times.
✓ Branch 3 taken 497 times.
✓ Branch 4 taken 1594 times.
✓ Branch 5 taken 106307013 times.
✓ Branch 6 taken 341742 times.
✓ Branch 7 taken 106307013 times.
213185082 table->has_invalid_stats() || table_def_shutdown_in_progress) {
1734 341742 tc->remove_table(table);
1735 341742 mysql_mutex_lock(&LOCK_open);
1736 341742 intern_close_table(table);
1737 341742 mysql_mutex_unlock(&LOCK_open);
1738 } else
1739 106307013 tc->release_table(thd, table);
1740
1741 106650563 tc->unlock();
1742 106651240 }
1743
1744 /* move one table to free list */
1745
1746 106647711 void close_thread_table(THD *thd, TABLE **table_ptr) {
1747 106647711 TABLE *table = *table_ptr;
1748
1/2
✓ Branch 0 taken 106650456 times.
✗ Branch 1 not taken.
106647711 DBUG_TRACE;
1749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106650456 times.
106650456 assert(table->key_read == 0);
1750
3/4
✓ Branch 0 taken 106649172 times.
✓ Branch 1 taken 1284 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 106649172 times.
106650456 assert(!table->file || table->file->inited == handler::NONE);
1751 mysql_mutex_assert_not_owner(&LOCK_open);
1752 /*
1753 The metadata lock must be released after giving back
1754 the table to the table cache.
1755 */
1756
2/4
✓ Branch 0 taken 106650282 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 106650282 times.
106650456 assert(thd->mdl_context.owns_equal_or_stronger_lock(
1757 MDL_key::TABLE, table->s->db.str, table->s->table_name.str, MDL_SHARED));
1758 106650282 table->mdl_ticket = nullptr;
1759 106650282 table->pos_in_table_list = nullptr;
1760
1761
1/2
✓ Branch 0 taken 106649363 times.
✗ Branch 1 not taken.
106650282 mysql_mutex_lock(&thd->LOCK_thd_data);
1762
1763
5/6
✓ Branch 0 taken 47552 times.
✓ Branch 1 taken 106601811 times.
✓ Branch 2 taken 47552 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 47552 times.
✓ Branch 5 taken 106601141 times.
106649363 if (unlikely(opt_userstat && table->file)) {
1764
1/2
✓ Branch 0 taken 47552 times.
✗ Branch 1 not taken.
47552 table->file->update_global_table_stats();
1765
1/2
✓ Branch 0 taken 47552 times.
✗ Branch 1 not taken.
47552 table->file->update_global_index_stats();
1766 }
1767
1768 106648693 *table_ptr = table->next;
1769
1/2
✓ Branch 0 taken 106649936 times.
✗ Branch 1 not taken.
106648693 mysql_mutex_unlock(&thd->LOCK_thd_data);
1770
1771 /*
1772 It is not safe to call the below code for TABLE objects for which
1773 handler::open() has not been called (for example, we use such objects
1774 while updating information about views which depend on table being
1775 ALTERed). Another possibly unsafe case is when TABLE/handler object
1776 has been marked as invalid (for example, it is unsafe to call
1777 handler::reset() for partitioned InnoDB tables after in-place ALTER
1778 TABLE API commit phase).
1779 */
1780
3/4
✓ Branch 0 taken 106649979 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106421063 times.
✓ Branch 3 taken 228916 times.
106649936 if (!table->has_invalid_dict()) {
1781 /* Avoid having MERGE tables with attached children in unused_tables. */
1782
1/2
✓ Branch 0 taken 106421269 times.
✗ Branch 1 not taken.
106421063 table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
1783 /* Free memory and reset for next loop. */
1784
1/2
✓ Branch 0 taken 106421055 times.
✗ Branch 1 not taken.
106421269 free_blob_buffers_and_reset(table, MAX_TDC_BLOB_SIZE);
1785
1/2
✓ Branch 0 taken 106420908 times.
✗ Branch 1 not taken.
106421055 table->file->ha_reset();
1786 }
1787
1788 /* Do this *before* entering the LOCK_open critical section. */
1789
2/4
✓ Branch 0 taken 106649993 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 106649638 times.
✗ Branch 3 not taken.
106649824 if (table->file != nullptr) table->file->unbind_psi();
1790
1791
1/2
✓ Branch 0 taken 106651043 times.
✗ Branch 1 not taken.
106649469 release_or_close_table(thd, table);
1792 106651043 }
1793
1794 /* close_temporary_tables' internal, 4 is due to uint4korr definition */
1795 1503 static inline uint tmpkeyval(TABLE *table) {
1796 1503 return uint4korr(table->s->table_cache_key.str +
1797 1503 table->s->table_cache_key.length - 4);
1798 }
1799
1800 /*
1801 Close all temporary tables created by 'CREATE TEMPORARY TABLE' for thread
1802 creates one DROP TEMPORARY TABLE binlog event for each pseudo-thread.
1803
1804 TODO: In future, we should have temporary_table= 0 and
1805 replica_open_temp_tables.fetch_add() at one place instead of repeating
1806 it all across the function. An alternative would be to use
1807 close_temporary_table() instead of close_temporary() that maintains
1808 the correct invariant regarding empty list of temporary tables
1809 and zero replica_open_temp_tables already.
1810 */
1811
1812 1146730 bool close_temporary_tables(THD *thd) {
1813
1/2
✓ Branch 0 taken 1148028 times.
✗ Branch 1 not taken.
1146730 DBUG_TRACE;
1814 TABLE *table;
1815 1148028 TABLE *next = nullptr;
1816 TABLE *prev_table;
1817 /* Assume thd->variables.option_bits has OPTION_QUOTE_SHOW_CREATE */
1818 1148028 bool was_quote_show = true;
1819 1148028 bool error = false;
1820 1148028 int slave_closed_temp_tables = 0;
1821
1822
2/2
✓ Branch 0 taken 1147008 times.
✓ Branch 1 taken 1020 times.
1148028 if (!thd->temporary_tables) return false;
1823
1824
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1017 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3 times.
1020 assert(!thd->slave_thread ||
1825 thd->system_thread != SYSTEM_THREAD_SLAVE_WORKER);
1826
1827 /*
1828 Ensure we don't have open HANDLERs for tables we are about to close.
1829 This is necessary when close_temporary_tables() is called as part
1830 of execution of BINLOG statement (e.g. for format description event).
1831 */
1832
1/2
✓ Branch 0 taken 1030 times.
✗ Branch 1 not taken.
1020 mysql_ha_rm_temporary_tables(thd);
1833
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1029 times.
1030 if (!mysql_bin_log.is_open()) {
1834 TABLE *tmp_next;
1835
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_lock(&thd->LOCK_temporary_tables);
1836
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 for (TABLE *t = thd->temporary_tables; t; t = tmp_next) {
1837 1 tmp_next = t->next;
1838
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_lock_remove(thd, thd->lock, t);
1839 /*
1840 We should not meet temporary tables created by ALTER TABLE here.
1841 It is responsibility of ALTER statement to close them. Otherwise
1842 it might be necessary to remove them from DD as well.
1843 */
1844
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(t->s->tmp_table_def);
1845
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 close_temporary(thd, t, true, true);
1846 1 slave_closed_temp_tables++;
1847 }
1848
1849 1 thd->temporary_tables = nullptr;
1850
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
1851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (thd->slave_thread) {
1852 atomic_replica_open_temp_tables -= slave_closed_temp_tables;
1853 thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables -=
1854 slave_closed_temp_tables;
1855 }
1856
1857 1 return false;
1858 }
1859
1860 /*
1861 We are about to generate DROP TEMPORARY TABLE statements for all
1862 the left out temporary tables. If GTID_NEXT is set (e.g. if user
1863 did SET GTID_NEXT just before disconnecting the client), we must
1864 ensure that it will be able to generate GTIDs for the statements
1865 with this server's UUID. Therefore we set gtid_next to
1866 AUTOMATIC_GTID.
1867 */
1868
1/2
✓ Branch 0 taken 1029 times.
✗ Branch 1 not taken.
1029 gtid_state->update_on_rollback(thd);
1869 1029 thd->variables.gtid_next.set_automatic();
1870
1871 /*
1872 We must separate transactional temp tables and
1873 non-transactional temp tables in two distinct DROP statements
1874 to avoid the splitting if a slave server reads from this binlog.
1875 */
1876
1877 /* Better add "if exists", in case a RESET MASTER has been done */
1878 1029 const char stub[] = "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
1879 1029 uint stub_len = sizeof(stub) - 1;
1880 char buf_trans[256], buf_non_trans[256];
1881 String s_query_trans =
1882 1029 String(buf_trans, sizeof(buf_trans), system_charset_info);
1883 String s_query_non_trans =
1884 1029 String(buf_non_trans, sizeof(buf_non_trans), system_charset_info);
1885 1029 bool found_user_tables = false;
1886 1029 bool found_trans_table = false;
1887 1029 bool found_non_trans_table = false;
1888
1889 1029 memcpy(buf_trans, stub, stub_len);
1890 1029 memcpy(buf_non_trans, stub, stub_len);
1891
1892 /*
1893 Insertion sort of temp tables by pseudo_thread_id to build ordered list
1894 of sublists of equal pseudo_thread_id
1895 */
1896
1/2
✓ Branch 0 taken 1029 times.
✗ Branch 1 not taken.
1029 mysql_mutex_lock(&thd->LOCK_temporary_tables);
1897
1898
2/2
✓ Branch 0 taken 169 times.
✓ Branch 1 taken 1029 times.
1198 for (prev_table = thd->temporary_tables, table = prev_table->next; table;
1899 169 prev_table = table, table = table->next) {
1900 TABLE *prev_sorted /* same as for prev_table */, *sorted;
1901 /*
1902 We should not meet temporary tables created by ALTER TABLE here.
1903 It is responsibility of ALTER statement to close them. Otherwise
1904 it might be necessary to remove them from DD as well.
1905 */
1906
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 169 times.
169 assert(table->s->tmp_table_def);
1907
2/2
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 3 times.
169 if (is_user_table(table)) {
1908
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 113 times.
166 if (!found_user_tables) found_user_tables = true;
1909 166 for (prev_sorted = nullptr, sorted = thd->temporary_tables;
1910
2/2
✓ Branch 0 taken 676 times.
✓ Branch 1 taken 142 times.
818 sorted != table; prev_sorted = sorted, sorted = sorted->next) {
1911
6/6
✓ Branch 0 taken 670 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 18 times.
✓ Branch 3 taken 652 times.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 652 times.
676 if (!is_user_table(sorted) || tmpkeyval(sorted) > tmpkeyval(table)) {
1912 /* move into the sorted part of the list from the unsorted */
1913 24 prev_table->next = table->next;
1914 24 table->next = sorted;
1915
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 11 times.
24 if (prev_sorted) {
1916 13 prev_sorted->next = table;
1917 } else {
1918 11 thd->temporary_tables = table;
1919 }
1920 24 table = prev_table;
1921 24 break;
1922 }
1923 }
1924 }
1925 }
1926
1927 /* We always quote db,table names though it is slight overkill */
1928
4/6
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 976 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 53 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1029 times.
1029 if (found_user_tables && !(was_quote_show = (thd->variables.option_bits &
1929 OPTION_QUOTE_SHOW_CREATE))) {
1930 thd->variables.option_bits |= OPTION_QUOTE_SHOW_CREATE;
1931 }
1932
1933 /*
1934 Make LEX consistent with DROP TEMPORARY TABLES statement which we
1935 are going to log. This is important for the binary logging code.
1936 */
1937 1029 LEX *lex = thd->lex;
1938 1029 enum_sql_command sav_sql_command = lex->sql_command;
1939 1029 bool sav_drop_temp = lex->drop_temporary;
1940 1029 lex->sql_command = SQLCOM_DROP_TABLE;
1941 1029 lex->drop_temporary = true;
1942
1943 /* scan sorted tmps to generate sequence of DROP */
1944
2/2
✓ Branch 0 taken 1176 times.
✓ Branch 1 taken 1029 times.
2205 for (table = thd->temporary_tables; table; table = next) {
1945
7/8
✓ Branch 0 taken 1170 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1170 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
✓ Branch 5 taken 1106 times.
✓ Branch 6 taken 64 times.
✓ Branch 7 taken 1112 times.
1176 if (is_user_table(table) && table->should_binlog_drop_if_temp()) {
1946 64 bool save_thread_specific_used = thd->thread_specific_used;
1947 64 my_thread_id save_pseudo_thread_id = thd->variables.pseudo_thread_id;
1948 /* Set pseudo_thread_id to be that of the processed table */
1949 64 thd->variables.pseudo_thread_id = tmpkeyval(table);
1950 64 String db;
1951
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 db.append(table->s->db.str);
1952 /* Loop forward through all tables that belong to a common database
1953 within the sublist of common pseudo_thread_id to create single
1954 DROP query
1955 */
1956 64 for (s_query_trans.length(stub_len), s_query_non_trans.length(stub_len),
1957 64 found_trans_table = false, found_non_trans_table = false;
1958
2/2
✓ Branch 0 taken 99 times.
✓ Branch 1 taken 1 times.
100 table && is_user_table(table) &&
1959
4/4
✓ Branch 0 taken 95 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 91 times.
✓ Branch 3 taken 4 times.
194 tmpkeyval(table) == thd->variables.pseudo_thread_id &&
1960
4/4
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 50 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 64 times.
345 table->s->db.length == db.length() &&
1961
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 5 times.
91 strcmp(table->s->db.str, db.ptr()) == 0;
1962 86 table = next) {
1963 /* Separate transactional from non-transactional temp tables */
1964
2/4
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 86 times.
✗ Branch 3 not taken.
86 if (table->should_binlog_drop_if_temp()) {
1965 /* Separate transactional from non-transactional temp tables */
1966
2/2
✓ Branch 0 taken 72 times.
✓ Branch 1 taken 14 times.
86 if (table->s->tmp_table == TRANSACTIONAL_TMP_TABLE) {
1967 72 found_trans_table = true;
1968 /*
1969 We are going to add ` around the table names and possible more
1970 due to special characters
1971 */
1972 72 append_identifier(thd, &s_query_trans, table->s->table_name.str,
1973
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 strlen(table->s->table_name.str));
1974
1/2
✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
72 s_query_trans.append(',');
1975
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 } else if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE) {
1976 14 found_non_trans_table = true;
1977 /*
1978 We are going to add ` around the table names and possible more
1979 due to special characters
1980 */
1981 14 append_identifier(thd, &s_query_non_trans, table->s->table_name.str,
1982
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 strlen(table->s->table_name.str));
1983
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 s_query_non_trans.append(',');
1984 }
1985 }
1986
1987 86 next = table->next;
1988
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 mysql_lock_remove(thd, thd->lock, table);
1989
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 close_temporary(thd, table, true, true);
1990 86 slave_closed_temp_tables++;
1991 }
1992
1/2
✓ Branch 0 taken 64 times.
✗ Branch 1 not taken.
64 thd->clear_error();
1993 64 const CHARSET_INFO *cs_save = thd->variables.character_set_client;
1994 64 thd->variables.character_set_client = system_charset_info;
1995 64 thd->thread_specific_used = true;
1996
1997
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 6 times.
64 if (found_trans_table) {
1998 58 Query_log_event qinfo(thd, s_query_trans.ptr(),
1999 58 s_query_trans.length() - 1, false, true, false,
2000
1/2
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
58 0);
2001 58 qinfo.db = db.ptr();
2002 58 qinfo.db_len = db.length();
2003 58 thd->variables.character_set_client = cs_save;
2004
2005 58 thd->get_stmt_da()->set_overwrite_status(true);
2006
2/4
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 58 times.
116 if ((error = (mysql_bin_log.write_event(&qinfo) ||
2007
4/8
✓ Branch 0 taken 58 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 58 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 58 times.
58 mysql_bin_log.commit(thd, true) || error))) {
2008 /*
2009 If we're here following THD::cleanup, thence the connection
2010 has been closed already. So lets print a message to the
2011 error log instead of pushing yet another error into the
2012 Diagnostics_area.
2013
2014 Also, we keep the error flag so that we propagate the error
2015 up in the stack. This way, if we're the SQL thread we notice
2016 that close_temporary_tables failed. (Actually, the SQL
2017 thread only calls close_temporary_tables while applying old
2018 Start_log_event_v3 events.)
2019 */
2020 LogErr(ERROR_LEVEL, ER_BINLOG_FAILED_TO_WRITE_DROP_FOR_TEMP_TABLES);
2021 }
2022 58 thd->get_stmt_da()->set_overwrite_status(false);
2023 58 }
2024
2025
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 54 times.
64 if (found_non_trans_table) {
2026 10 Query_log_event qinfo(thd, s_query_non_trans.ptr(),
2027 10 s_query_non_trans.length() - 1, false, true,
2028
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 false, 0);
2029 10 qinfo.db = db.ptr();
2030 10 qinfo.db_len = db.length();
2031 10 thd->variables.character_set_client = cs_save;
2032
2033 10 thd->get_stmt_da()->set_overwrite_status(true);
2034
2/4
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
20 if ((error = (mysql_bin_log.write_event(&qinfo) ||
2035
4/8
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10 times.
10 mysql_bin_log.commit(thd, true) || error))) {
2036 /*
2037 If we're here following THD::cleanup, thence the connection
2038 has been closed already. So lets print a message to the
2039 error log instead of pushing yet another error into the
2040 Diagnostics_area.
2041
2042 Also, we keep the error flag so that we propagate the error
2043 up in the stack. This way, if we're the SQL thread we notice
2044 that close_temporary_tables failed. (Actually, the SQL
2045 thread only calls close_temporary_tables while applying old
2046 Start_log_event_v3 events.)
2047 */
2048 LogErr(ERROR_LEVEL, ER_BINLOG_FAILED_TO_WRITE_DROP_FOR_TEMP_TABLES);
2049 }
2050 10 thd->get_stmt_da()->set_overwrite_status(false);
2051 10 }
2052
2053 64 thd->variables.pseudo_thread_id = save_pseudo_thread_id;
2054 64 thd->thread_specific_used = save_thread_specific_used;
2055 64 } else {
2056 1112 next = table->next;
2057 /*
2058 This is for those cases when we have acquired lock but drop temporary
2059 table will not be logged.
2060 */
2061
1/2
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
1112 mysql_lock_remove(thd, thd->lock, table);
2062
1/2
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
1112 close_temporary(thd, table, true, true);
2063 1112 slave_closed_temp_tables++;
2064 }
2065 }
2066 1029 thd->temporary_tables = nullptr;
2067
1/2
✓ Branch 0 taken 1029 times.
✗ Branch 1 not taken.
1029 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
2068 1029 lex->drop_temporary = sav_drop_temp;
2069 1029 lex->sql_command = sav_sql_command;
2070
2071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1029 times.
1029 if (!was_quote_show)
2072 thd->variables.option_bits &=
2073 ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
2074
2075
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1026 times.
1029 if (thd->slave_thread) {
2076 3 atomic_replica_open_temp_tables -= slave_closed_temp_tables;
2077
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables -=
2078 slave_closed_temp_tables;
2079 }
2080
2081 1029 return error;
2082 1148038 }
2083
2084 /**
2085 Find table in global list.
2086
2087 @param table Pointer to table list
2088 @param db_name Data base name
2089 @param table_name Table name
2090
2091 @returns Pointer to found table.
2092 @retval NULL Table not found
2093 */
2094
2095 5173842 TABLE_LIST *find_table_in_global_list(TABLE_LIST *table, const char *db_name,
2096 const char *table_name) {
2097
2/2
✓ Branch 0 taken 374818 times.
✓ Branch 1 taken 4976465 times.
5351283 for (; table; table = table->next_global) {
2098
2/2
✓ Branch 0 taken 369335 times.
✓ Branch 1 taken 5483 times.
374818 if ((table->table == nullptr ||
2099
2/2
✓ Branch 0 taken 365373 times.
✓ Branch 1 taken 3962 times.
369335 table->table->s->tmp_table == NO_TMP_TABLE) &&
2100
2/2
✓ Branch 0 taken 273352 times.
✓ Branch 1 taken 97504 times.
370856 strcmp(table->db, db_name) == 0 &&
2101
2/2
✓ Branch 0 taken 197377 times.
✓ Branch 1 taken 75975 times.
273352 strcmp(table->table_name, table_name) == 0)
2102 197377 break;
2103 }
2104 5173842 return table;
2105 }
2106
2107 /**
2108 Test that table is unique (It's only exists once in the table list)
2109
2110 @param table table to be checked (must be updatable base table)
2111 @param table_list list of tables
2112 @param check_alias whether to check tables' aliases
2113
2114 NOTE: to exclude derived tables from check we use following mechanism:
2115 a) during derived table processing set THD::derived_tables_processing
2116 b) Query_block::prepare set SELECT::exclude_from_table_unique_test if
2117 THD::derived_tables_processing set. (we can't use JOIN::execute
2118 because for PS we perform only Query_block::prepare, but we can't set
2119 this flag in Query_block::prepare if we are not sure that we are in
2120 derived table processing loop, because multi-update call fix_fields()
2121 for some its items (which mean Query_block::prepare for subqueries)
2122 before unique_table call to detect which tables should be locked for
2123 write).
2124 c) find_dup_table skip all tables which belong to SELECT with
2125 SELECT::exclude_from_table_unique_test set.
2126 Also SELECT::exclude_from_table_unique_test used to exclude from check
2127 tables of main SELECT of multi-delete and multi-update
2128
2129 We also skip tables with TABLE_LIST::prelocking_placeholder set,
2130 because we want to allow SELECTs from them, and their modification
2131 will rise the error anyway.
2132
2133 TODO: when we will have table/view change detection we can do this check
2134 only once for PS/SP
2135
2136 @retval !=0 found duplicate
2137 @retval 0 if table is unique
2138 */
2139
2140 5065270 static TABLE_LIST *find_dup_table(const TABLE_LIST *table,
2141 TABLE_LIST *table_list, bool check_alias) {
2142 TABLE_LIST *res;
2143 const char *d_name, *t_name, *t_alias;
2144
1/2
✓ Branch 0 taken 5065855 times.
✗ Branch 1 not taken.
5065270 DBUG_TRACE;
2145
5/8
✓ Branch 0 taken 5065792 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5065788 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 5065766 times.
✓ Branch 6 taken 22 times.
✗ Branch 7 not taken.
5065855 DBUG_PRINT("enter", ("table alias: %s", table->alias));
2146
2147
2/4
✓ Branch 0 taken 5065797 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5065797 times.
5065788 assert(table == table->updatable_base_table());
2148 /*
2149 If this function called for CREATE command that we have not opened table
2150 (table->table equal to 0) and right names is in current TABLE_LIST
2151 object.
2152 */
2153
2/2
✓ Branch 0 taken 5065782 times.
✓ Branch 1 taken 15 times.
5065797 if (table->table) {
2154 /* All MyISAMMRG children are plain MyISAM tables. */
2155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5065782 times.
5065782 assert(table->table->file->ht->db_type != DB_TYPE_MRG_MYISAM);
2156
2157 /* temporary table is always unique */
2158
2/2
✓ Branch 0 taken 109931 times.
✓ Branch 1 taken 4955851 times.
5065782 if (table->table->s->tmp_table != NO_TMP_TABLE) return nullptr;
2159 }
2160
2161 4955866 d_name = table->db;
2162 4955866 t_name = table->table_name;
2163 4955866 t_alias = table->alias;
2164
2165
5/8
✓ Branch 0 taken 4955703 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4955775 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22 times.
✓ Branch 5 taken 4955753 times.
✓ Branch 6 taken 17 times.
✗ Branch 7 not taken.
4955866 DBUG_PRINT("info", ("real table: %s.%s", d_name, t_name));
2166 for (;;) {
2167 /*
2168 Table is unique if it is present only once in the global list
2169 of tables and once in the list of table locks.
2170 */
2171
3/4
✓ Branch 0 taken 5146727 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4949475 times.
✓ Branch 3 taken 197252 times.
5147055 if (!(res = find_table_in_global_list(table_list, d_name, t_name))) break;
2172
2173 /* Skip if same underlying table. */
2174
3/4
✓ Branch 0 taken 197310 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 186906 times.
✓ Branch 3 taken 10404 times.
197252 if (res->table && (res->table == table->table)) goto next;
2175
2176 /* Skip if table alias does not match. */
2177
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 10240 times.
10346 if (check_alias) {
2178 212 if (lower_case_table_names
2179
5/6
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 94 times.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 102 times.
200 ? my_strcasecmp(files_charset_info, t_alias, res->alias)
2180 94 : strcmp(t_alias, res->alias))
2181 4 goto next;
2182 }
2183
2184 /*
2185 Skip if marked to be excluded (could be a derived table) or if
2186 entry is a prelocking placeholder.
2187 */
2188
3/4
✓ Branch 0 taken 10344 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4324 times.
✓ Branch 3 taken 6020 times.
10342 if (res->query_block && !res->query_block->exclude_from_table_unique_test &&
2189
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6018 times.
6020 !res->prelocking_placeholder)
2190 6018 break;
2191
2192 /*
2193 If we found entry of this table or table of SELECT which already
2194 processed in derived table or top select of multi-update/multi-delete
2195 (exclude_from_table_unique_test) or prelocking placeholder.
2196 */
2197 4324 next:
2198 191234 table_list = res->next_global;
2199
5/8
✓ Branch 0 taken 191285 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 191286 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 8 times.
✓ Branch 5 taken 191278 times.
✓ Branch 6 taken 7 times.
✗ Branch 7 not taken.
191234 DBUG_PRINT("info",
2200 ("found same copy of table or table which we should skip"));
2201 }
2202 4955493 return res;
2203 5065424 }
2204
2205 /**
2206 Test that the subject table of INSERT/UPDATE/DELETE/CREATE
2207 or (in case of MyISAMMRG) one of its children are not used later
2208 in the query.
2209
2210 For MyISAMMRG tables, it is assumed that all the underlying
2211 tables of @c table (if any) are listed right after it and that
2212 their @c parent_l field points at the main table.
2213
2214 @param table table to be checked (must be updatable base table)
2215 @param table_list List of tables to check against
2216 @param check_alias whether to check tables' aliases
2217
2218 @retval non-NULL The table list element for the table that
2219 represents the duplicate.
2220 @retval NULL No duplicates found.
2221 */
2222
2223 5064065 TABLE_LIST *unique_table(const TABLE_LIST *table, TABLE_LIST *table_list,
2224 bool check_alias) {
2225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5064566 times.
5064065 assert(table == table->updatable_base_table());
2226
2227 TABLE_LIST *dup;
2228
3/4
✓ Branch 0 taken 5064601 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1194 times.
✓ Branch 3 taken 5063407 times.
5064566 if (table->table && table->table->file->ht->db_type == DB_TYPE_MRG_MYISAM) {
2229 TABLE_LIST *child;
2230 1194 dup = nullptr;
2231 /* Check duplicates of all merge children. */
2232
4/4
✓ Branch 0 taken 2475 times.
✓ Branch 1 taken 1056 times.
✓ Branch 2 taken 2349 times.
✓ Branch 3 taken 126 times.
3531 for (child = table->next_global; child && child->parent_l == table;
2233 2337 child = child->next_global) {
2234
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2337 times.
2349 if ((dup = find_dup_table(child, child->next_global, check_alias))) break;
2235 }
2236 1194 } else
2237 5063372 dup = find_dup_table(table, table_list, check_alias);
2238 5064630 return dup;
2239 }
2240
2241 /**
2242 Issue correct error message in case we found 2 duplicate tables which
2243 prevent some update operation
2244
2245 @param update table which we try to update
2246 @param operation name of update operation
2247 @param duplicate duplicate table which we found
2248
2249 @note here we hide view underlying tables if we have them.
2250 */
2251
2252 207 void update_non_unique_table_error(TABLE_LIST *update, const char *operation,
2253 TABLE_LIST *duplicate) {
2254 207 update = update->top_table();
2255 207 duplicate = duplicate->top_table();
2256
4/4
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 43 times.
✓ Branch 3 taken 15 times.
343 if (!update->is_view() || !duplicate->is_view() ||
2257 58 update->view_query() == duplicate->view_query() ||
2258
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 update->table_name_length != duplicate->table_name_length ||
2259
1/2
✓ Branch 0 taken 43 times.
✗ Branch 1 not taken.
43 update->db_length != duplicate->db_length ||
2260
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 25 times.
43 my_strcasecmp(table_alias_charset, update->table_name,
2261
4/4
✓ Branch 0 taken 78 times.
✓ Branch 1 taken 129 times.
✓ Branch 2 taken 189 times.
✓ Branch 3 taken 18 times.
285 duplicate->table_name) != 0 ||
2262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
18 my_strcasecmp(table_alias_charset, update->db, duplicate->db) != 0) {
2263 /*
2264 it is not the same view repeated (but it can be parts of the same copy
2265 of view), so we have to hide underlying tables.
2266 */
2267
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 129 times.
189 if (update->is_view()) {
2268 // Issue the ER_NON_INSERTABLE_TABLE error for an INSERT
2269
6/6
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 25 times.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 45 times.
100 if (duplicate->is_view() &&
2270 40 update->view_query() == duplicate->view_query())
2271
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 9 times.
15 my_error(!strncmp(operation, "INSERT", 6) ? ER_NON_INSERTABLE_TABLE
2272 : ER_NON_UPDATABLE_TABLE,
2273 MYF(0), update->alias, operation);
2274 else
2275
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 20 times.
45 my_error(ER_VIEW_PREVENT_UPDATE, MYF(0),
2276 45 (duplicate->is_view() ? duplicate->alias : update->alias),
2277 operation, update->alias);
2278 60 return;
2279 }
2280
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 104 times.
129 if (duplicate->is_view()) {
2281 25 my_error(ER_VIEW_PREVENT_UPDATE, MYF(0), duplicate->alias, operation,
2282 update->alias);
2283 25 return;
2284 }
2285 }
2286 122 my_error(ER_UPDATE_TABLE_USED, MYF(0), update->alias);
2287 }
2288
2289 /**
2290 Find temporary table specified by database and table names in the
2291 THD::temporary_tables list.
2292
2293 @return TABLE instance if a temporary table has been found; NULL otherwise.
2294 */
2295
2296 191978 TABLE *find_temporary_table(THD *thd, const char *db, const char *table_name) {
2297 char key[MAX_DBKEY_LENGTH];
2298
1/2
✓ Branch 0 taken 191978 times.
✗ Branch 1 not taken.
191978 size_t key_length = create_table_def_key_tmp(thd, db, table_name, key);
2299 383956 return find_temporary_table(thd, key, key_length);
2300 }
2301
2302 /**
2303 Find a temporary table specified by TABLE_LIST instance in the
2304 THD::temporary_tables list.
2305
2306 @return TABLE instance if a temporary table has been found; NULL otherwise.
2307 */
2308
2309 12108051 TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl) {
2310 const char *key;
2311 size_t key_length;
2312 char key_suffix[TMP_TABLE_KEY_EXTRA];
2313 TABLE *table;
2314
2315
1/2
✓ Branch 0 taken 12108923 times.
✗ Branch 1 not taken.
12108051 key_length = get_table_def_key(tl, &key);
2316
2317 12108923 int4store(key_suffix, thd->server_id);
2318 12108862 int4store(key_suffix + 4, thd->variables.pseudo_thread_id);
2319
2320
2/2
✓ Branch 0 taken 2091274 times.
✓ Branch 1 taken 11784453 times.
13875727 for (table = thd->temporary_tables; table; table = table->next) {
2321 2091274 if ((table->s->table_cache_key.length ==
2322
2/2
✓ Branch 0 taken 1310363 times.
✓ Branch 1 taken 780911 times.
2091274 key_length + TMP_TABLE_KEY_EXTRA) &&
2323
2/2
✓ Branch 0 taken 324212 times.
✓ Branch 1 taken 986151 times.
1310363 !memcmp(table->s->table_cache_key.str, key, key_length) &&
2324
2/2
✓ Branch 0 taken 324192 times.
✓ Branch 1 taken 20 times.
324212 !memcmp(table->s->table_cache_key.str + key_length, key_suffix,
2325 TMP_TABLE_KEY_EXTRA))
2326 324192 return table;
2327 }
2328 11784453 return nullptr;
2329 }
2330
2331 /**
2332 Find a temporary table specified by a key in the THD::temporary_tables list.
2333
2334 @return TABLE instance if a temporary table has been found; NULL otherwise.
2335 */
2336
2337 191978 static TABLE *find_temporary_table(THD *thd, const char *table_key,
2338 size_t table_key_length) {
2339
2/2
✓ Branch 0 taken 739359 times.
✓ Branch 1 taken 191867 times.
931226 for (TABLE *table = thd->temporary_tables; table; table = table->next) {
2340
2/2
✓ Branch 0 taken 451920 times.
✓ Branch 1 taken 287439 times.
739359 if (table->s->table_cache_key.length == table_key_length &&
2341
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 451809 times.
451920 !memcmp(table->s->table_cache_key.str, table_key, table_key_length)) {
2342 111 return table;
2343 }
2344 }
2345
2346 191867 return nullptr;
2347 }
2348
2349 /**
2350 Drop a temporary table.
2351
2352 - If the table is locked with LOCK TABLES or by prelocking,
2353 unlock it and remove it from the list of locked tables
2354 (THD::lock). Currently only transactional temporary tables
2355 are locked.
2356 - Close the temporary table.
2357 - Remove the table from the list of temporary tables.
2358 */
2359
2360 46226 void drop_temporary_table(THD *thd, TABLE_LIST *table_list) {
2361
1/2
✓ Branch 0 taken 46226 times.
✗ Branch 1 not taken.
46226 DBUG_TRACE;
2362
3/8
✓ Branch 0 taken 46226 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46226 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 46226 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
46226 DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table_list->db,
2363 table_list->table_name));
2364
2365
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 46226 times.
46226 assert(is_temporary_table(table_list));
2366
2367 46226 TABLE *table = table_list->table;
2368
2369
2/4
✓ Branch 0 taken 46226 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 46226 times.
46226 assert(!table->query_id || table->query_id == thd->query_id);
2370
2371 /*
2372 If LOCK TABLES list is not empty and contains this table,
2373 unlock the table and remove the table from this list.
2374 */
2375
1/2
✓ Branch 0 taken 46226 times.
✗ Branch 1 not taken.
46226 mysql_lock_remove(thd, thd->lock, table);
2376
1/2
✓ Branch 0 taken 46226 times.
✗ Branch 1 not taken.
46226 close_temporary_table(thd, table, true, true);
2377 46226 table_list->table = nullptr;
2378 46226 }
2379
2380 /*
2381 unlink from thd->temporary tables and close temporary table
2382 */
2383
2384 151913 void close_temporary_table(THD *thd, TABLE *table, bool free_share,
2385 bool delete_table) {
2386
1/2
✓ Branch 0 taken 151918 times.
✗ Branch 1 not taken.
151913 DBUG_TRACE;
2387
5/8
✓ Branch 0 taken 151918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 151918 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 151917 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
151918 DBUG_PRINT("tmptable",
2388 ("closing table: '%s'.'%s' %p alias: '%s'", table->s->db.str,
2389 table->s->table_name.str, table, table->alias));
2390
2391
1/2
✓ Branch 0 taken 151913 times.
✗ Branch 1 not taken.
151918 mysql_mutex_lock(&thd->LOCK_temporary_tables);
2392
2393
2/2
✓ Branch 0 taken 4859 times.
✓ Branch 1 taken 147054 times.
151913 if (table->prev) {
2394 4859 table->prev->next = table->next;
2395
2/2
✓ Branch 0 taken 2366 times.
✓ Branch 1 taken 2493 times.
4859 if (table->prev->next) table->next->prev = table->prev;
2396 } else {
2397 /* removing the item from the list */
2398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 147054 times.
147054 assert(table == thd->temporary_tables);
2399 /*
2400 slave must reset its temporary list pointer to zero to exclude
2401 passing non-zero value to end_slave via rli->save_temporary_tables
2402 when no temp tables opened, see an invariant below.
2403 */
2404 147054 thd->temporary_tables = table->next;
2405
2/2
✓ Branch 0 taken 666 times.
✓ Branch 1 taken 146388 times.
147054 if (thd->temporary_tables) table->next->prev = nullptr;
2406 }
2407
2/2
✓ Branch 0 taken 2561 times.
✓ Branch 1 taken 149352 times.
151913 if (thd->slave_thread) {
2408 /* natural invariant of temporary_tables */
2409
2/6
✓ Branch 0 taken 2561 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2561 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2561 assert(thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables ||
2410 !thd->temporary_tables);
2411 2561 --atomic_replica_open_temp_tables;
2412
1/2
✓ Branch 0 taken 2561 times.
✗ Branch 1 not taken.
2561 --thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables;
2413 }
2414
1/2
✓ Branch 0 taken 151918 times.
✗ Branch 1 not taken.
151913 close_temporary(thd, table, free_share, delete_table);
2415
2416
1/2
✓ Branch 0 taken 151918 times.
✗ Branch 1 not taken.
151918 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
2417
2418 151918 }
2419
2420 /*
2421 Close and delete a temporary table
2422
2423 NOTE
2424 This doesn't unlink table from thd->temporary
2425 If this is needed, use close_temporary_table()
2426 */
2427
2428 153119 void close_temporary(THD *thd, TABLE *table, bool free_share,
2429 bool delete_table) {
2430
1/2
✓ Branch 0 taken 153120 times.
✗ Branch 1 not taken.
153119 handlerton *table_type = table->s->db_type();
2431
1/2
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
153120 DBUG_TRACE;
2432
5/8
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 153124 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 153123 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
153124 DBUG_PRINT("tmptable", ("closing table: '%s'.'%s'", table->s->db.str,
2433 table->s->table_name.str));
2434
2435
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 153110 times.
153124 if (unlikely(opt_userstat)) {
2436
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 table->file->update_global_table_stats();
2437
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 table->file->update_global_index_stats();
2438 }
2439
2440
1/2
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
153119 free_io_cache(table);
2441
1/2
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
153124 closefrm(table, false);
2442
2/2
✓ Branch 0 taken 48563 times.
✓ Branch 1 taken 104561 times.
153124 if (delete_table) {
2443
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 48563 times.
48563 assert(thd);
2444 48563 rm_temporary_table(thd, table_type, table->s->path.str,
2445
1/2
✓ Branch 0 taken 48563 times.
✗ Branch 1 not taken.
48563 table->s->tmp_table_def);
2446 }
2447
2448
1/2
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
153124 if (free_share) {
2449
1/2
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
153124 free_table_share(table->s);
2450 153124 destroy(table);
2451
1/2
✓ Branch 0 taken 153124 times.
✗ Branch 1 not taken.
153124 my_free(table);
2452 }
2453 153124 }
2454
2455 /*
2456 Used by ALTER TABLE when the table is a temporary one. It changes something
2457 only if the ALTER contained a RENAME clause (otherwise, table_name is the old
2458 name).
2459 Prepares a table cache key, which is the concatenation of db, table_name and
2460 thd->slave_proxy_id, separated by '\0'.
2461 */
2462
2463 1116 bool rename_temporary_table(THD *thd, TABLE *table, const char *db,
2464 const char *table_name) {
2465 char *key;
2466 size_t key_length;
2467 1116 TABLE_SHARE *share = table->s;
2468
1/2
✓ Branch 0 taken 1116 times.
✗ Branch 1 not taken.
1116 DBUG_TRACE;
2469
2470
2/4
✓ Branch 0 taken 1116 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1116 times.
1116 if (!(key = (char *)share->mem_root.Alloc(MAX_DBKEY_LENGTH)))
2471 return true; /* purecov: inspected */
2472
2473
1/2
✓ Branch 0 taken 1116 times.
✗ Branch 1 not taken.
1116 key_length = create_table_def_key_tmp(thd, db, table_name, key);
2474 1116 share->set_table_cache_key(key, key_length);
2475 /* Also update table name in DD object. Database name is kept reset. */
2476
2/4
✓ Branch 0 taken 1116 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1116 times.
✗ Branch 3 not taken.
1116 share->tmp_table_def->set_name(table_name);
2477 1116 return false;
2478 1116 }
2479
2480 /**
2481 Force all other threads to stop using the table by upgrading
2482 metadata lock on it and remove unused TABLE instances from cache.
2483
2484 @param thd Thread handler
2485 @param table Table to remove from cache
2486 @param function HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
2487 HA_EXTRA_FORCE_REOPEN if table is not be used
2488 HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed
2489
2490 @note When returning, the table will be unusable for other threads
2491 until metadata lock is downgraded.
2492
2493 @retval false Success.
2494 @retval true Failure (e.g. because thread was killed).
2495 */
2496
2497 115646 bool wait_while_table_is_used(THD *thd, TABLE *table,
2498 enum ha_extra_function function) {
2499
1/2
✓ Branch 0 taken 115646 times.
✗ Branch 1 not taken.
115646 DBUG_TRACE;
2500
5/8
✓ Branch 0 taken 115646 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 115646 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 115645 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
115646 DBUG_PRINT("enter", ("table: '%s' share: %p db_stat: %u version: %lu",
2501 table->s->table_name.str, table->s, table->db_stat,
2502 table->s->version()));
2503
2504
3/4
✓ Branch 0 taken 115646 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 115620 times.
115646 if (thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE,
2505 thd->variables.lock_wait_timeout))
2506 26 return true;
2507
2508 115620 tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN, table->s->db.str,
2509
1/2
✓ Branch 0 taken 115620 times.
✗ Branch 1 not taken.
115620 table->s->table_name.str, false);
2510 /* extra() call must come only after all instances above are closed */
2511
1/2
✓ Branch 0 taken 115620 times.
✗ Branch 1 not taken.
115620 (void)table->file->ha_extra(function);
2512 115620 return false;
2513 115646 }
2514
2515 /**
2516 Check that table exists in data-dictionary or in some storage engine.
2517
2518 @param thd Thread context
2519 @param table Table list element
2520 @param[out] exists Out parameter which is set to true if table
2521 exists and to false otherwise.
2522
2523 @note If there is no table in data-dictionary but it exists in one
2524 of engines (e.g. it was created on another node of NDB cluster)
2525 this function will fetch and add proper table description to
2526 the data-dictionary.
2527
2528 @retval true Some error occurred
2529 @retval false No error. 'exists' out parameter set accordingly.
2530 */
2531
2532 1948223 static bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists) {
2533
1/2
✓ Branch 0 taken 1948356 times.
✗ Branch 1 not taken.
1948223 DBUG_TRACE;
2534
2535 1948356 *exists = true;
2536
2537
2/4
✓ Branch 0 taken 1948282 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1948282 times.
1948356 assert(thd->mdl_context.owns_equal_or_stronger_lock(
2538 MDL_key::TABLE, table->db, table->table_name, MDL_SHARED));
2539
2540
3/4
✓ Branch 0 taken 1948214 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1948213 times.
1948282 if (dd::table_exists(thd->dd_client(), table->db, table->table_name, exists))
2541 1 return true; // Error is already reported.
2542
2543
2/2
✓ Branch 0 taken 1389918 times.
✓ Branch 1 taken 558295 times.
1948213 if (*exists) goto end;
2544
2545 /* Table doesn't exist. Check if some engine can provide it. */
2546
2/4
✓ Branch 0 taken 558331 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 558331 times.
558295 if (ha_check_if_table_exists(thd, table->db, table->table_name, exists)) {
2547 my_printf_error(ER_OUT_OF_RESOURCES,
2548 "Failed to open '%-.64s', error while "
2549 "unpacking from engine",
2550 MYF(0), table->table_name);
2551 return true;
2552 }
2553 558331 end:
2554 1948249 return false;
2555 1948250 }
2556
2557 /**
2558 An error handler which converts, if possible, ER_LOCK_DEADLOCK error
2559 that can occur when we are trying to acquire a metadata lock to
2560 a request for back-off and re-start of open_tables() process.
2561 */
2562
2563 class MDL_deadlock_handler : public Internal_error_handler {
2564 public:
2565 125347243 MDL_deadlock_handler(Open_table_context *ot_ctx_arg)
2566 125347243 : m_ot_ctx(ot_ctx_arg), m_is_active(false) {}
2567
2568 222 bool handle_condition(THD *, uint sql_errno, const char *,
2569 Sql_condition::enum_severity_level *,
2570 const char *) override {
2571
4/4
✓ Branch 0 taken 201 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 34 times.
✓ Branch 3 taken 167 times.
222 if (!m_is_active && sql_errno == ER_LOCK_DEADLOCK) {
2572 /* Disable the handler to avoid infinite recursion. */
2573 34 m_is_active = true;
2574 34 (void)m_ot_ctx->request_backoff_action(
2575 Open_table_context::OT_BACKOFF_AND_RETRY, nullptr);
2576 34 m_is_active = false;
2577 /*
2578 If the above back-off request failed, a new instance of
2579 ER_LOCK_DEADLOCK error was emitted. Thus the current
2580 instance of error condition can be treated as handled.
2581 */
2582 34 return true;
2583 }
2584 188 return false;
2585 }
2586
2587 private:
2588 /** Open table context to be used for back-off request. */
2589 Open_table_context *m_ot_ctx;
2590 /**
2591 Indicates that we are already in the process of handling
2592 ER_LOCK_DEADLOCK error. Allows to re-emit the error from
2593 the error handler without falling into infinite recursion.
2594 */
2595 bool m_is_active;
2596 };
2597
2598 /**
2599 Try to acquire an MDL lock for a table being opened.
2600
2601 @param[in,out] thd Session context, to report errors.
2602 @param[out] ot_ctx Open table context, to hold the back off
2603 state. If we failed to acquire a lock
2604 due to a lock conflict, we add the
2605 failed request to the open table context.
2606 @param[in,out] table_list Table list element for the table being opened.
2607 Its "mdl_request" member specifies the MDL lock
2608 to be requested. If we managed to acquire a
2609 ticket (no errors or lock conflicts occurred),
2610 TABLE_LIST::mdl_request contains a reference
2611 to it on return. However, is not modified if
2612 MDL lock type- modifying flags were provided.
2613 We also use TABLE_LIST::lock_type member to
2614 detect cases when MDL_SHARED_WRITE_LOW_PRIO
2615 lock should be acquired instead of the normal
2616 MDL_SHARED_WRITE lock.
2617 @param[in] flags flags MYSQL_OPEN_FORCE_SHARED_MDL,
2618 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL or
2619 MYSQL_OPEN_FAIL_ON_MDL_CONFLICT
2620 @sa open_table().
2621 @param[out] mdl_ticket Only modified if there was no error.
2622 If we managed to acquire an MDL
2623 lock, contains a reference to the
2624 ticket, otherwise is set to NULL.
2625
2626 @retval true An error occurred.
2627 @retval false No error, but perhaps a lock conflict, check mdl_ticket.
2628 */
2629
2630 107220603 static bool open_table_get_mdl_lock(THD *thd, Open_table_context *ot_ctx,
2631 TABLE_LIST *table_list, uint flags,
2632 MDL_ticket **mdl_ticket) {
2633 107220603 MDL_request *mdl_request = &table_list->mdl_request;
2634 107220603 MDL_request new_mdl_request;
2635
2636
2/2
✓ Branch 0 taken 129537 times.
✓ Branch 1 taken 107091479 times.
107221016 if (flags &
2637 (MYSQL_OPEN_FORCE_SHARED_MDL | MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL)) {
2638 /*
2639 MYSQL_OPEN_FORCE_SHARED_MDL flag means that we are executing
2640 PREPARE for a prepared statement and want to override
2641 the type-of-operation aware metadata lock which was set
2642 in the parser/during view opening with a simple shared
2643 metadata lock.
2644 This is necessary to allow concurrent execution of PREPARE
2645 and LOCK TABLES WRITE statement against the same table.
2646
2647 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL flag means that we open
2648 the table in order to get information about it for one of I_S
2649 queries and also want to override the type-of-operation aware
2650 shared metadata lock which was set earlier (e.g. during view
2651 opening) with a high-priority shared metadata lock.
2652 This is necessary to avoid unnecessary waiting and extra
2653 ER_WARN_I_S_SKIPPED_TABLE warnings when accessing I_S tables.
2654
2655 These two flags are mutually exclusive.
2656 */
2657
3/4
✓ Branch 0 taken 54429 times.
✓ Branch 1 taken 75108 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 54429 times.
129537 assert(!(flags & MYSQL_OPEN_FORCE_SHARED_MDL) ||
2658 !(flags & MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL));
2659
2660
3/4
✓ Branch 0 taken 54429 times.
✓ Branch 1 taken 75108 times.
✓ Branch 2 taken 129542 times.
✗ Branch 3 not taken.
129537 MDL_REQUEST_INIT_BY_KEY(&new_mdl_request, &mdl_request->key,
2661 (flags & MYSQL_OPEN_FORCE_SHARED_MDL)
2662 ? MDL_SHARED
2663 : MDL_SHARED_HIGH_PRIO,
2664 MDL_TRANSACTION);
2665 129542 mdl_request = &new_mdl_request;
2666 214186750 } else if (thd->variables.low_priority_updates &&
2667
6/6
✓ Branch 0 taken 3765 times.
✓ Branch 1 taken 107087714 times.
✓ Branch 2 taken 1005 times.
✓ Branch 3 taken 2760 times.
✓ Branch 4 taken 201 times.
✓ Branch 5 taken 107091305 times.
107092511 mdl_request->type == MDL_SHARED_WRITE &&
2668
2/2
✓ Branch 0 taken 960 times.
✓ Branch 1 taken 45 times.
1005 (table_list->lock_descriptor().type == TL_WRITE_DEFAULT ||
2669
2/2
✓ Branch 0 taken 156 times.
✓ Branch 1 taken 831 times.
960 table_list->lock_descriptor().type ==
2670 TL_WRITE_CONCURRENT_DEFAULT)) {
2671 /*
2672 We are in @@low_priority_updates=1 mode and are going to acquire
2673 SW metadata lock on a table which for which neither LOW_PRIORITY nor
2674 HIGH_PRIORITY clauses were used explicitly.
2675 To keep compatibility with THR_LOCK locks and to avoid starving out
2676 concurrent LOCK TABLES READ statements, we need to acquire the low-prio
2677 version of SW lock instead of a normal SW lock in this case.
2678 */
2679
1/2
✓ Branch 0 taken 201 times.
✗ Branch 1 not taken.
201 MDL_REQUEST_INIT_BY_KEY(&new_mdl_request, &mdl_request->key,
2680 MDL_SHARED_WRITE_LOW_PRIO, MDL_TRANSACTION);
2681 201 mdl_request = &new_mdl_request;
2682 }
2683
2684
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107221048 times.
107221048 if (flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT) {
2685 /*
2686 When table is being open in order to get data for I_S table,
2687 we might have some tables not only open but also locked (e.g. when
2688 this happens under LOCK TABLES or in a stored function).
2689 As a result by waiting on a conflicting metadata lock to go away
2690 we may create a deadlock which won't entirely belong to the
2691 MDL subsystem and thus won't be detectable by this subsystem's
2692 deadlock detector.
2693 To avoid such situation we skip the trouble-making table if
2694 there is a conflicting lock.
2695 */
2696 if (thd->mdl_context.try_acquire_lock(mdl_request)) return true;
2697 if (mdl_request->ticket == nullptr) {
2698 my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0), mdl_request->key.db_name(),
2699 mdl_request->key.name());
2700 return true;
2701 }
2702 } else {
2703 /*
2704 We are doing a normal table open. Let us try to acquire a metadata
2705 lock on the table. If there is a conflicting lock, acquire_lock()
2706 will wait for it to go away. Sometimes this waiting may lead to a
2707 deadlock, with the following results:
2708 1) If a deadlock is entirely within MDL subsystem, it is
2709 detected by the deadlock detector of this subsystem.
2710 ER_LOCK_DEADLOCK error is produced. Then, the error handler
2711 that is installed prior to the call to acquire_lock() attempts
2712 to request a back-off and retry. Upon success, ER_LOCK_DEADLOCK
2713 error is suppressed, otherwise propagated up the calling stack.
2714 2) Otherwise, a deadlock may occur when the wait-for graph
2715 includes edges not visible to the MDL deadlock detector.
2716 One such example is a wait on an InnoDB row lock, e.g. when:
2717 conn C1 gets SR MDL lock on t1 with SELECT * FROM t1
2718 conn C2 gets a row lock on t2 with SELECT * FROM t2 FOR UPDATE
2719 conn C3 gets in and waits on C1 with DROP TABLE t0, t1
2720 conn C2 continues and blocks on C3 with SELECT * FROM t0
2721 conn C1 deadlocks by waiting on C2 by issuing SELECT * FROM
2722 t2 LOCK IN SHARE MODE.
2723 Such circular waits are currently only resolved by timeouts,
2724 e.g. @@innodb_lock_wait_timeout or @@lock_wait_timeout.
2725
2726 Note that we want to force DML deadlock weight for our context
2727 when acquiring locks in this place. This is done to avoid situation
2728 when LOCK TABLES statement, which acquires strong SNRW and SRO locks
2729 on implicitly used tables, deadlocks with a concurrent DDL statement
2730 and the DDL statement is aborted since it is chosen as a deadlock
2731 victim. It is better to choose LOCK TABLES as a victim in this case
2732 as a deadlock can be easily caught here and handled by back-off and retry,
2733 without reporting any error to the user.
2734 We still have a few weird cases, like FLUSH TABLES <table-list> WITH
2735 READ LOCK, where we use "strong" metadata locks and open_tables() is
2736 called with some metadata locks pre-acquired. In these cases we still
2737 want to use DDL deadlock weight as back-off is not possible.
2738 */
2739 107221048 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
2740
2741
1/2
✓ Branch 0 taken 107220943 times.
✗ Branch 1 not taken.
107220795 thd->push_internal_handler(&mdl_deadlock_handler);
2742 107220943 thd->mdl_context.set_force_dml_deadlock_weight(ot_ctx->can_back_off());
2743
2744 bool result =
2745
1/2
✓ Branch 0 taken 107221084 times.
✗ Branch 1 not taken.
107220948 thd->mdl_context.acquire_lock(mdl_request, ot_ctx->get_timeout());
2746
2747 107221084 thd->mdl_context.set_force_dml_deadlock_weight(false);
2748
1/2
✓ Branch 0 taken 107220946 times.
✗ Branch 1 not taken.
107221090 thd->pop_internal_handler();
2749
2750
6/6
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 107220770 times.
✓ Branch 2 taken 169 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 169 times.
✓ Branch 5 taken 107220777 times.
107220946 if (result && !ot_ctx->can_recover_from_failed_open()) return true;
2751
2/2
✓ Branch 0 taken 107220884 times.
✓ Branch 1 taken 155 times.
107220946 }
2752 107220884 *mdl_ticket = mdl_request->ticket;
2753 107220884 return false;
2754 }
2755
2756 /**
2757 Check if table's share is being removed from the table definition
2758 cache and, if yes, wait until the flush is complete.
2759
2760 @param thd Thread context.
2761 @param db Database name.
2762 @param table_name Table name.
2763 @param wait_timeout Timeout for waiting.
2764 @param deadlock_weight Weight of this wait for deadlock detector.
2765
2766 @retval false Success. Share is up to date or has been flushed.
2767 @retval true Error (OOM, our was killed, the wait resulted
2768 in a deadlock or timeout). Reported.
2769 */
2770
2771 20 static bool tdc_wait_for_old_version(THD *thd, const char *db,
2772 const char *table_name, ulong wait_timeout,
2773 uint deadlock_weight) {
2774 TABLE_SHARE *share;
2775 20 bool res = false;
2776
2777 20 mysql_mutex_lock(&LOCK_open);
2778
6/6
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 7 times.
✓ Branch 5 taken 13 times.
28 if ((share = get_cached_table_share(db, table_name)) &&
2779 8 share->has_old_version()) {
2780 struct timespec abstime;
2781
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 set_timespec(&abstime, wait_timeout);
2782
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 res = share->wait_for_old_version(thd, &abstime, deadlock_weight);
2783 }
2784 20 mysql_mutex_unlock(&LOCK_open);
2785 20 return res;
2786 }
2787
2788 /**
2789 Add a dummy LEX object for a view.
2790
2791 @param thd Thread context
2792 @param table_list The list of tables in the view
2793
2794 @retval true error occurred
2795 @retval false view place holder successfully added
2796 */
2797
2798 28 bool add_view_place_holder(THD *thd, TABLE_LIST *table_list) {
2799
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 Prepared_stmt_arena_holder ps_arena_holder(thd);
2800
2/4
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
28 LEX *lex_obj = new (thd->mem_root) st_lex_local;
2801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (lex_obj == nullptr) return true;
2802 28 table_list->set_view_query(lex_obj);
2803 // Create empty list of view_tables.
2804 28 table_list->view_tables =
2805
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 new (thd->mem_root) mem_root_deque<TABLE_LIST *>(thd->mem_root);
2806
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28 times.
28 if (table_list->view_tables == nullptr) return true;
2807 28 return false;
2808 28 }
2809
2810 /**
2811 Open a base table.
2812
2813 @param thd Thread context.
2814 @param table_list Open first table in list.
2815 @param ot_ctx Context with flags which modify how open works
2816 and which is used to recover from a failed
2817 open_table() attempt.
2818 Some examples of flags:
2819 MYSQL_OPEN_IGNORE_FLUSH - Open table even if
2820 someone has done a flush. No version number
2821 checking is done.
2822 MYSQL_OPEN_HAS_MDL_LOCK - instead of acquiring
2823 metadata locks rely on that caller already has
2824 appropriate ones.
2825
2826 Uses a cache of open tables to find a TABLE instance not in use.
2827
2828 If TABLE_LIST::open_strategy is set to OPEN_IF_EXISTS, the table is
2829 opened only if it exists. If the open strategy is OPEN_STUB, the
2830 underlying table is never opened. In both cases, metadata locks are
2831 always taken according to the lock strategy.
2832
2833 @retval true Open failed. "action" parameter may contain type of action
2834 needed to remedy problem before retrying again.
2835 @retval false Success. Members of TABLE_LIST structure are filled properly
2836 (e.g. TABLE_LIST::table is set for real tables and
2837 TABLE_LIST::view is set for views).
2838 */
2839
2840 107935297 bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx) {
2841 107935297 TABLE *table = nullptr;
2842 107935297 TABLE_SHARE *share = nullptr;
2843 const char *key;
2844 size_t key_length;
2845 107935297 const char *alias = table_list->alias;
2846 107935297 uint flags = ot_ctx->get_flags();
2847 107935970 MDL_ticket *mdl_ticket = nullptr;
2848 107935970 int error = 0;
2849 107935970 bool backup_protection_acquired = false;
2850
2851
1/2
✓ Branch 0 taken 107937667 times.
✗ Branch 1 not taken.
107935970 DBUG_TRACE;
2852
2853 // Temporary tables and derived tables are not allowed:
2854
3/4
✓ Branch 0 taken 107937762 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 107937813 times.
✓ Branch 3 taken 8 times.
107937667 assert(!is_temporary_table(table_list) && !table_list->is_derived());
2855
2856 /*
2857 The table must not be opened already. The table can be pre-opened for
2858 some statements if it is a temporary table.
2859
2860 open_temporary_table() must be used to open temporary tables.
2861 A derived table cannot be opened with this.
2862 */
2863
3/4
✓ Branch 0 taken 107869445 times.
✓ Branch 1 taken 68324 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 107869445 times.
107937813 assert(table_list->is_view() || table_list->table == nullptr);
2864
2865 /* an open table operation needs a lot of the stack space */
2866
3/4
✓ Branch 0 taken 107937929 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 107937927 times.
107937769 if (check_stack_overrun(thd, STACK_MIN_SIZE_FOR_OPEN, (uchar *)&alias))
2867 2 return true;
2868
2869 // New DD- In current_thd->is_strict_mode() mode we call open_table
2870 // on new DD tables like mysql.tables/* when CREATE fails and we
2871 // try to abort the operation and invoke quick_rm_table().
2872 // Currently, we ignore deleting table in strict mode. Need to fix this.
2873 // TODO.
2874
2875
5/6
✓ Branch 0 taken 107937498 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 107937493 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 3 times.
107937927 DBUG_EXECUTE_IF("kill_query_on_open_table_from_tz_find", {
2876 /*
2877 When on calling my_tz_find the following
2878 tables are opened in specified order: time_zone_name,
2879 time_zone, time_zone_transition_type,
2880 time_zone_transition. Emulate killing a query
2881 on opening the second table in the list.
2882 */
2883 if (!strcmp("time_zone", table_list->table_name))
2884 thd->killed = THD::KILL_QUERY;
2885 });
2886
2887
6/6
✓ Branch 0 taken 16845531 times.
✓ Branch 1 taken 91090760 times.
✓ Branch 2 taken 137 times.
✓ Branch 3 taken 16845662 times.
✓ Branch 4 taken 137 times.
✓ Branch 5 taken 107936422 times.
107936291 if (!(flags & MYSQL_OPEN_IGNORE_KILLED) && thd->killed) return true;
2888
2889 /*
2890 Check if we're trying to take a write lock in a read only transaction.
2891
2892 Note that we allow write locks on log tables as otherwise logging
2893 to general/slow log would be disabled in read only transactions.
2894 */
2895
6/6
✓ Branch 0 taken 26865884 times.
✓ Branch 1 taken 81070363 times.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 26865856 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 107936219 times.
107936450 if (table_list->mdl_request.is_write_lock_request() && thd->tx_read_only &&
2896
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK))) {
2897
1/2
✓ Branch 0 taken 28 times.
✗ Branch 1 not taken.
28 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
2898 28 return true;
2899 }
2900
2901 /*
2902 FLUSH TABLES is ignored for DD, I_S and P_S tables/views.
2903 Hence setting MYSQL_OPEN_IGNORE_FLUSH flag.
2904 */
2905
8/8
✓ Branch 0 taken 107497907 times.
✓ Branch 1 taken 438312 times.
✓ Branch 2 taken 14264595 times.
✓ Branch 3 taken 93233341 times.
✓ Branch 4 taken 744772 times.
✓ Branch 5 taken 13519890 times.
✓ Branch 6 taken 94416437 times.
✓ Branch 7 taken 13519878 times.
122200881 if (table_list->is_system_view || belongs_to_dd_table(table_list) ||
2906 14264595 belongs_to_p_s(table_list))
2907 94416437 flags |= MYSQL_OPEN_IGNORE_FLUSH;
2908
2909
1/2
✓ Branch 0 taken 107937304 times.
✗ Branch 1 not taken.
107936315 key_length = get_table_def_key(table_list, &key);
2910
2911 // If a table in a secondary storage engine has been requested,
2912 // adjust the key to refer to the secondary table.
2913 107937304 std::string secondary_key;
2914
2/2
✓ Branch 0 taken 549 times.
✓ Branch 1 taken 107935895 times.
107936444 if ((flags & MYSQL_OPEN_SECONDARY_ENGINE) != 0) {
2915
1/2
✓ Branch 0 taken 549 times.
✗ Branch 1 not taken.
1098 secondary_key = create_table_def_key_secondary(
2916 549 table_list->get_db_name(), table_list->get_table_name());
2917 549 key = secondary_key.data();
2918 549 key_length = secondary_key.length();
2919 }
2920
2921 /*
2922 If we're in pre-locked or LOCK TABLES mode, let's try to find the
2923 requested table in the list of pre-opened and locked tables. If the
2924 table is not there, return an error - we can't open not pre-opened
2925 tables in pre-locked/LOCK TABLES mode.
2926
2927 There is a special case where we allow opening not pre-opened tables
2928 in LOCK TABLES mode for new DD tables. The reason is as following.
2929 With new DD, IS system views need to be accessible in LOCK TABLE
2930 mode without user explicitly calling LOCK TABLE on IS view or its
2931 underlying DD tables. This is required to keep the old behavior the
2932 MySQL server had without new DD.
2933
2934 In case user executes IS system view under LOCK TABLE mode
2935 (LTM and not prelocking), then MySQL server implicitly opens system
2936 view and related DD tables. Such DD tables are then implicitly closed
2937 upon end of statement execution.
2938
2939 Our goal is to hide DD tables from users, so there is no possibility of
2940 explicit locking DD table using LOCK TABLE. In case user does LOCK TABLE
2941 on IS system view explicitly, MySQL server throws a error.
2942
2943 TODO: move this block into a separate function.
2944 */
2945
6/6
✓ Branch 0 taken 146683 times.
✓ Branch 1 taken 107788586 times.
✓ Branch 2 taken 146351 times.
✓ Branch 3 taken 332 times.
✓ Branch 4 taken 57983 times.
✓ Branch 5 taken 107877286 times.
108081620 if (thd->locked_tables_mode && !(flags & MYSQL_OPEN_GET_NEW_TABLE) &&
2946
2/2
✓ Branch 0 taken 93494 times.
✓ Branch 1 taken 52857 times.
146351 !(in_LTM(thd) &&
2947
4/4
✓ Branch 0 taken 80015 times.
✓ Branch 1 taken 13479 times.
✓ Branch 2 taken 5949 times.
✓ Branch 3 taken 74066 times.
93494 (table_list->is_system_view || belongs_to_dd_table(table_list) ||
2948
2/2
✓ Branch 0 taken 5126 times.
✓ Branch 1 taken 823 times.
5949 belongs_to_p_s(table_list)))) { // Using table locks
2949 57983 TABLE *best_table = nullptr;
2950 57983 int best_distance = INT_MIN;
2951
2/2
✓ Branch 0 taken 289822 times.
✓ Branch 1 taken 57926 times.
347748 for (table = thd->open_tables; table; table = table->next) {
2952
2/2
✓ Branch 0 taken 133982 times.
✓ Branch 1 taken 155840 times.
289822 if (table->s->table_cache_key.length == key_length &&
2953
2/2
✓ Branch 0 taken 62588 times.
✓ Branch 1 taken 71394 times.
133982 !memcmp(table->s->table_cache_key.str, key, key_length)) {
2954
1/2
✓ Branch 0 taken 62588 times.
✗ Branch 1 not taken.
62588 if (!my_strcasecmp(system_charset_info, table->alias, alias) &&
2955
6/6
✓ Branch 0 taken 61398 times.
✓ Branch 1 taken 1190 times.
✓ Branch 2 taken 61329 times.
✓ Branch 3 taken 69 times.
✓ Branch 4 taken 60547 times.
✓ Branch 5 taken 2041 times.
123917 table->query_id != thd->query_id && /* skip tables already used */
2956
2/2
✓ Branch 0 taken 56245 times.
✓ Branch 1 taken 5084 times.
61329 (thd->locked_tables_mode == LTM_LOCK_TABLES ||
2957
2/2
✓ Branch 0 taken 55463 times.
✓ Branch 1 taken 782 times.
56245 table->query_id == 0)) {
2958 60547 int distance = ((int)table->reginfo.lock_type -
2959 60547 (int)table_list->lock_descriptor().type);
2960
2961 /*
2962 Find a table that either has the exact lock type requested,
2963 or has the best suitable lock. In case there is no locked
2964 table that has an equal or higher lock than requested,
2965 we us the closest matching lock to be able to produce an error
2966 message about wrong lock mode on the table. The best_table
2967 is changed if bd < 0 <= d or bd < d < 0 or 0 <= d < bd.
2968
2969 distance < 0 - No suitable lock found
2970 distance > 0 - we have lock mode higher then we require
2971 distance == 0 - we have lock mode exactly which we need
2972 */
2973
5/6
✓ Branch 0 taken 57328 times.
✓ Branch 1 taken 3219 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 57328 times.
✓ Branch 4 taken 3217 times.
✓ Branch 5 taken 2 times.
60547 if ((best_distance < 0 && distance > best_distance) ||
2974
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 3210 times.
3217 (distance >= 0 && distance < best_distance)) {
2975 57335 best_distance = distance;
2976 57335 best_table = table;
2977
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 57278 times.
57335 if (best_distance == 0) {
2978 /*
2979 We have found a perfect match and can finish iterating
2980 through open tables list. Check for table use conflict
2981 between calling statement and SP/trigger is done in
2982 lock_tables().
2983 */
2984 57 break;
2985 }
2986 }
2987 }
2988 }
2989 }
2990
2/2
✓ Branch 0 taken 57324 times.
✓ Branch 1 taken 659 times.
57983 if (best_table) {
2991 57324 table = best_table;
2992 57324 table->query_id = thd->query_id;
2993
3/8
✓ Branch 0 taken 57324 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57324 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 57324 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
57324 DBUG_PRINT("info", ("Using locked table"));
2994 57324 goto reset;
2995 }
2996 /*
2997 Is this table a view and not a base table?
2998 (it is work around to allow to open view with locked tables,
2999 real fix will be made after definition cache will be made)
3000
3001 Since opening of view which was not explicitly locked by LOCK
3002 TABLES breaks metadata locking protocol (potentially can lead
3003 to deadlocks) it should be disallowed.
3004 */
3005
3/4
✓ Branch 0 taken 659 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 597 times.
✓ Branch 3 taken 62 times.
659 if (thd->mdl_context.owns_equal_or_stronger_lock(
3006 MDL_key::TABLE, table_list->db, table_list->table_name,
3007 MDL_SHARED)) {
3008 /*
3009 Note that we can't be 100% sure that it is a view since it's
3010 possible that we either simply have not found unused TABLE
3011 instance in THD::open_tables list or were unable to open table
3012 during prelocking process (in this case in theory we still
3013 should hold shared metadata lock on it).
3014 */
3015
1/2
✓ Branch 0 taken 597 times.
✗ Branch 1 not taken.
597 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
3016 597 const dd::View *view = nullptr;
3017
4/10
✓ Branch 0 taken 597 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 597 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 538 times.
✓ Branch 5 taken 59 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
1194 if (!thd->dd_client()->acquire(table_list->db, table_list->table_name,
3018
4/8
✓ Branch 0 taken 597 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 597 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 597 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 597 times.
✗ Branch 7 not taken.
1791 &view) &&
3019
2/2
✓ Branch 0 taken 538 times.
✓ Branch 1 taken 59 times.
597 view != nullptr) {
3020 /*
3021 If parent_l of the table_list is non null then a merge table
3022 has this view as child table, which is not supported.
3023 */
3024
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 537 times.
538 if (table_list->parent_l) {
3025
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_WRONG_MRG_TABLE, MYF(0));
3026 1 return true;
3027 }
3028
3029 /*
3030 In the case of a CREATE, add a dummy LEX object to
3031 indicate the presence of a view amd skip processing the
3032 existing view.
3033 */
3034
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 537 times.
537 if (table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE)
3035 return add_view_place_holder(thd, table_list);
3036
3037
3/4
✓ Branch 0 taken 537 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 529 times.
✓ Branch 3 taken 8 times.
537 if (!tdc_open_view(thd, table_list, key, key_length)) {
3038
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 529 times.
529 assert(table_list->is_view());
3039 529 return false; // VIEW
3040 }
3041 }
3042
2/2
✓ Branch 0 taken 67 times.
✓ Branch 1 taken 530 times.
597 }
3043 /*
3044 No table in the locked tables list. In case of explicit LOCK TABLES
3045 this can happen if a user did not include the table into the list.
3046 In case of pre-locked mode locked tables list is generated automatically,
3047 so we may only end up here if the table did not exist when
3048 locked tables list was created.
3049 */
3050
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 100 times.
129 if (thd->locked_tables_mode == LTM_PRELOCKED)
3051
1/2
✓ Branch 0 taken 29 times.
✗ Branch 1 not taken.
29 my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db, table_list->alias);
3052 else
3053
1/2
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
100 my_error(ER_TABLE_NOT_LOCKED, MYF(0), alias);
3054 129 return true;
3055 }
3056
3057 // Non pre-locked/LOCK TABLES mode, and not using secondary storage engine.
3058 // This is the normal use case.
3059
3060
2/2
✓ Branch 0 taken 107218315 times.
✓ Branch 1 taken 658971 times.
107877286 if ((flags & (MYSQL_OPEN_HAS_MDL_LOCK | MYSQL_OPEN_SECONDARY_ENGINE)) == 0) {
3061 /*
3062 We are not under LOCK TABLES and going to acquire write-lock/
3063 modify the base table. We need to acquire protection against
3064 global read lock until end of this statement in order to have
3065 this statement blocked by active FLUSH TABLES WITH READ LOCK.
3066
3067 We don't block acquire this protection under LOCK TABLES as
3068 such protection already acquired at LOCK TABLES time and
3069 not released until UNLOCK TABLES.
3070
3071 We don't block statements which modify only temporary tables
3072 as these tables are not preserved by backup by any form of
3073 backup which uses FLUSH TABLES WITH READ LOCK.
3074
3075 TODO: The fact that we sometimes acquire protection against
3076 GRL only when we encounter table to be write-locked
3077 slightly increases probability of deadlock.
3078 This problem will be solved once Alik pushes his
3079 temporary table refactoring patch and we can start
3080 pre-acquiring metadata locks at the beginning of
3081 open_tables() call.
3082 */
3083 107218315 if (table_list->mdl_request.is_write_lock_request() &&
3084
2/2
✓ Branch 0 taken 25319482 times.
✓ Branch 1 taken 1035519 times.
26355001 !(flags &
3085 (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | MYSQL_OPEN_FORCE_SHARED_MDL |
3086 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
3087
4/4
✓ Branch 0 taken 26355001 times.
✓ Branch 1 taken 80864221 times.
✓ Branch 2 taken 13546091 times.
✓ Branch 3 taken 93673353 times.
133574445 MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) &&
3088
2/2
✓ Branch 0 taken 13545997 times.
✓ Branch 1 taken 11773707 times.
25319482 !ot_ctx->has_protection_against_grl()) {
3089 13546091 MDL_request protection_request;
3090 13546652 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
3091
3092
3/4
✓ Branch 0 taken 13545321 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 13545301 times.
13545966 if (thd->global_read_lock.can_acquire_protection()) return true;
3093
3094
1/2
✓ Branch 0 taken 13546782 times.
✗ Branch 1 not taken.
13545301 MDL_REQUEST_INIT(&protection_request, MDL_key::GLOBAL, "", "",
3095 MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT);
3096
3097 /*
3098 Install error handler which if possible will convert deadlock error
3099 into request to back-off and restart process of opening tables.
3100
3101 Prefer this context as a victim in a deadlock when such a deadlock
3102 can be easily handled by back-off and retry.
3103 */
3104
1/2
✓ Branch 0 taken 13546497 times.
✗ Branch 1 not taken.
13546782 thd->push_internal_handler(&mdl_deadlock_handler);
3105 13546497 thd->mdl_context.set_force_dml_deadlock_weight(ot_ctx->can_back_off());
3106
3107
1/2
✓ Branch 0 taken 13547186 times.
✗ Branch 1 not taken.
13546055 bool result = thd->mdl_context.acquire_lock(&protection_request,
3108 ot_ctx->get_timeout());
3109
3110 /*
3111 Unlike in other places where we acquire protection against global read
3112 lock, the read_only state is not checked here since we check its state
3113 later in mysql_lock_tables()
3114 */
3115
3116 13547186 thd->mdl_context.set_force_dml_deadlock_weight(false);
3117
1/2
✓ Branch 0 taken 13547186 times.
✗ Branch 1 not taken.
13547187 thd->pop_internal_handler();
3118
3119
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13547169 times.
13547186 if (result) return true;
3120
3121 13547169 ot_ctx->set_has_protection_against_grl();
3122
2/2
✓ Branch 0 taken 13547172 times.
✓ Branch 1 taken 36 times.
13547206 }
3123
3124
5/6
✓ Branch 0 taken 107220932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 107220818 times.
✓ Branch 3 taken 114 times.
✓ Branch 4 taken 176 times.
✓ Branch 5 taken 107220756 times.
214441343 if (open_table_get_mdl_lock(thd, ot_ctx, table_list, flags, &mdl_ticket) ||
3125
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107220875 times.
107220818 mdl_ticket == nullptr) {
3126
2/4
✓ Branch 0 taken 176 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 176 times.
✗ Branch 3 not taken.
176 DEBUG_SYNC(thd, "before_open_table_wait_refresh");
3127 176 return true;
3128 }
3129
3/4
✓ Branch 0 taken 98372331 times.
✓ Branch 1 taken 8848455 times.
✓ Branch 2 taken 98372495 times.
✗ Branch 3 not taken.
107220756 DEBUG_SYNC(thd, "after_open_table_mdl_shared");
3130 } else {
3131 /*
3132 Grab reference to the MDL lock ticket that was acquired
3133 by the caller.
3134 */
3135 658971 mdl_ticket = table_list->mdl_request.ticket;
3136 }
3137
3138
2/2
✓ Branch 0 taken 106531246 times.
✓ Branch 1 taken 1348675 times.
107879921 if (table_list->open_strategy == TABLE_LIST::OPEN_IF_EXISTS ||
3139
2/2
✓ Branch 0 taken 600026 times.
✓ Branch 1 taken 105931220 times.
106531246 table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE) {
3140 bool exists;
3141
3142
3/4
✓ Branch 0 taken 1948242 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1948241 times.
2507032 if (check_if_table_exists(thd, table_list, &exists)) return true;
3143
3144 /*
3145 If the table does not exist then upgrade the lock to the EXCLUSIVE MDL
3146 lock.
3147 */
3148
2/2
✓ Branch 0 taken 558331 times.
✓ Branch 1 taken 1389910 times.
1948241 if (!exists) {
3149
2/2
✓ Branch 0 taken 558288 times.
✓ Branch 1 taken 43 times.
558331 if (table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE &&
3150
2/2
✓ Branch 0 taken 545824 times.
✓ Branch 1 taken 12464 times.
558288 !(flags & (MYSQL_OPEN_FORCE_SHARED_MDL |
3151 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))) {
3152 545824 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
3153
3154
1/2
✓ Branch 0 taken 545823 times.
✗ Branch 1 not taken.
545824 thd->push_internal_handler(&mdl_deadlock_handler);
3155
3156
3/4
✓ Branch 0 taken 489181 times.
✓ Branch 1 taken 56642 times.
✓ Branch 2 taken 489182 times.
✗ Branch 3 not taken.
545823 DEBUG_SYNC(thd, "before_upgrading_lock_from_S_to_X_for_create_table");
3157
1/2
✓ Branch 0 taken 545824 times.
✗ Branch 1 not taken.
545824 bool wait_result = thd->mdl_context.upgrade_shared_lock(
3158 table_list->mdl_request.ticket, MDL_EXCLUSIVE,
3159 thd->variables.lock_wait_timeout);
3160
3161
1/2
✓ Branch 0 taken 545823 times.
✗ Branch 1 not taken.
545824 thd->pop_internal_handler();
3162
3/4
✓ Branch 0 taken 489181 times.
✓ Branch 1 taken 56642 times.
✓ Branch 2 taken 489182 times.
✗ Branch 3 not taken.
545823 DEBUG_SYNC(thd, "after_upgrading_lock_from_S_to_X_for_create_table");
3163
3164 /* Deadlock or timeout occurred while upgrading the lock. */
3165
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 545818 times.
545824 if (wait_result) return true;
3166
2/2
✓ Branch 0 taken 545818 times.
✓ Branch 1 taken 6 times.
545824 }
3167
3168 558325 return false;
3169 }
3170
3171 /* Table exists. Let us try to open it. */
3172
2/2
✓ Branch 0 taken 67445 times.
✓ Branch 1 taken 105863775 times.
107321130 } else if (table_list->open_strategy == TABLE_LIST::OPEN_STUB)
3173 67445 return false;
3174
3175 107253685 retry_share : {
3176 107253703 Table_cache *tc = table_cache_manager.get_cache(thd);
3177
3178
1/2
✓ Branch 0 taken 107253682 times.
✗ Branch 1 not taken.
107253659 tc->lock();
3179
3180 /*
3181 Try to get unused TABLE object or at least pointer to
3182 TABLE_SHARE from the table cache.
3183 */
3184
2/2
✓ Branch 0 taken 107185402 times.
✓ Branch 1 taken 68309 times.
107253682 if (!table_list->is_view())
3185
1/2
✓ Branch 0 taken 107185000 times.
✗ Branch 1 not taken.
107185402 table = tc->get_table(thd, key, key_length, &share);
3186
3187
2/2
✓ Branch 0 taken 102491340 times.
✓ Branch 1 taken 4761969 times.
107253309 if (table) {
3188 /* We have found an unused TABLE object. */
3189
3190
2/2
✓ Branch 0 taken 9541492 times.
✓ Branch 1 taken 92949848 times.
102491340 if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) {
3191 /*
3192 TABLE_SHARE::version can only be initialised while holding the
3193 LOCK_open and in this case no one has a reference to the share
3194 object, if a reference exists to the share object it is necessary
3195 to lock both LOCK_open AND all table caches in order to update
3196 TABLE_SHARE::version. The same locks are required to increment
3197 refresh_version global variable.
3198
3199 As result it is safe to compare TABLE_SHARE::version and
3200 refresh_version values while having only lock on the table
3201 cache for this thread.
3202
3203 Table cache should not contain any unused TABLE objects with
3204 old versions.
3205 */
3206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9541630 times.
9541492 assert(!share->has_old_version());
3207
3208 /*
3209 Still some of already opened might become outdated (e.g. due to
3210 concurrent table flush). So we need to compare version of opened
3211 tables with version of TABLE object we just have got.
3212 */
3213
4/6
✓ Branch 0 taken 488246 times.
✓ Branch 1 taken 9053384 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 488309 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 9541693 times.
10029939 if (thd->open_tables &&
3214 488246 thd->open_tables->s->version() != share->version()) {
3215 tc->release_table(thd, table);
3216 tc->unlock();
3217 (void)ot_ctx->request_backoff_action(
3218 Open_table_context::OT_REOPEN_TABLES, nullptr);
3219 return true;
3220 }
3221 }
3222
1/2
✓ Branch 0 taken 102491482 times.
✗ Branch 1 not taken.
102491541 tc->unlock();
3223
3224 /* Call rebind_psi outside of the critical section. */
3225
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 102491482 times.
102491482 assert(table->file != nullptr);
3226
1/2
✓ Branch 0 taken 102491606 times.
✗ Branch 1 not taken.
102491482 table->file->rebind_psi();
3227
1/2
✓ Branch 0 taken 102491616 times.
✗ Branch 1 not taken.
102491606 table->file->ha_extra(HA_EXTRA_RESET_STATE);
3228
3229 102491616 thd->status_var.table_open_cache_hits++;
3230 102491616 goto table_found;
3231
2/2
✓ Branch 0 taken 471512 times.
✓ Branch 1 taken 4290457 times.
4761969 } else if (share) {
3232 /*
3233 We weren't able to get an unused TABLE object. Still we have
3234 found TABLE_SHARE for it. So let us try to create new TABLE
3235 for it. We start by incrementing share's reference count and
3236 checking its version.
3237 */
3238
1/2
✓ Branch 0 taken 471512 times.
✗ Branch 1 not taken.
471512 mysql_mutex_lock(&LOCK_open);
3239
1/2
✓ Branch 0 taken 471512 times.
✗ Branch 1 not taken.
471512 tc->unlock();
3240
1/2
✓ Branch 0 taken 471512 times.
✗ Branch 1 not taken.
471512 share->increment_ref_count();
3241 471512 goto share_found;
3242 } else {
3243 /*
3244 We have not found neither TABLE nor TABLE_SHARE object in
3245 table cache (this means that there are no TABLE objects for
3246 it in it).
3247 Let us try to get TABLE_SHARE from table definition cache or
3248 from disk and then to create TABLE object for it.
3249 */
3250
1/2
✓ Branch 0 taken 4290462 times.
✗ Branch 1 not taken.
4290457 tc->unlock();
3251 }
3252 }
3253
3254
1/2
✓ Branch 0 taken 4290470 times.
✗ Branch 1 not taken.
4290462 mysql_mutex_lock(&LOCK_open);
3255
3256
2/2
✓ Branch 0 taken 25430 times.
✓ Branch 1 taken 4265037 times.
4290467 if (!(share = get_table_share_with_discover(
3257 thd, table_list, key, key_length,
3258
1/2
✓ Branch 0 taken 4290467 times.
✗ Branch 1 not taken.
4290470 flags & MYSQL_OPEN_SECONDARY_ENGINE, &error))) {
3259
1/2
✓ Branch 0 taken 25430 times.
✗ Branch 1 not taken.
25430 mysql_mutex_unlock(&LOCK_open);
3260 /*
3261 If thd->is_error() is not set, we either need discover
3262 (error == 7), or the error was silenced by the prelocking
3263 handler (error == 0), in which case we should skip this
3264 table.
3265 */
3266
2/8
✗ Branch 0 not taken.
✓ Branch 1 taken 25430 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 25430 times.
25430 if (error == 7 && !thd->is_error()) {
3267 (void)ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
3268 table_list);
3269 }
3270 25430 return true;
3271 }
3272
3273 /*
3274 If a view is anticipated or the TABLE_SHARE object is a view, perform
3275 a version check for it without creating a TABLE object.
3276
3277 Note that there is no need to call TABLE_SHARE::has_old_version() as we
3278 do for regular tables, because view shares are always up to date.
3279 */
3280
6/6
✓ Branch 0 taken 4196777 times.
✓ Branch 1 taken 68260 times.
✓ Branch 2 taken 507389 times.
✓ Branch 3 taken 3689388 times.
✓ Branch 4 taken 575649 times.
✓ Branch 5 taken 3689388 times.
4265037 if (table_list->is_view() || share->is_view) {
3281 575649 bool view_open_result = true;
3282 /*
3283 If parent_l of the table_list is non null then a merge table
3284 has this view as child table, which is not supported.
3285 */
3286
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 575649 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
575649 if (table_list->parent_l) my_error(ER_WRONG_MRG_TABLE, MYF(0));
3287 /*
3288 Validate metadata version: in particular, that a view is opened when
3289 it is expected, or that a table is opened when it is expected.
3290 */
3291
3/4
✓ Branch 0 taken 575649 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 575631 times.
✓ Branch 3 taken 18 times.
575649 else if (check_and_update_table_version(thd, table_list, share))
3292 ;
3293
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 575601 times.
575631 else if (table_list->open_strategy == TABLE_LIST::OPEN_FOR_CREATE) {
3294 /*
3295 Skip reading the view definition if the open is for a table to be
3296 created. This scenario will happen only when there exists a view and
3297 the current CREATE TABLE request is with the same name.
3298 */
3299
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 release_table_share(share);
3300
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 mysql_mutex_unlock(&LOCK_open);
3301
3302 /*
3303 The LEX object is used by the executor and other parts of the
3304 code to detect the presence of a view. As this is
3305 OPEN_FOR_CREATE we skip the call to open_and_read_view(),
3306 which creates the LEX object, and create a dummy LEX object.
3307
3308 For SP and PS, LEX objects are created at the time of
3309 statement prepare and open_table() is called for every execute
3310 after that. Skip creation of LEX objects if it is already
3311 present.
3312 */
3313
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 28 times.
✗ Branch 3 not taken.
30 if (!table_list->is_view()) return add_view_place_holder(thd, table_list);
3314 2 return false;
3315 } else {
3316 /*
3317 Read definition of existing view.
3318 */
3319
1/2
✓ Branch 0 taken 575601 times.
✗ Branch 1 not taken.
575601 view_open_result = open_and_read_view(thd, share, table_list);
3320 }
3321
3322 /* TODO: Don't free this */
3323
1/2
✓ Branch 0 taken 575619 times.
✗ Branch 1 not taken.
575619 release_table_share(share);
3324
1/2
✓ Branch 0 taken 575619 times.
✗ Branch 1 not taken.
575619 mysql_mutex_unlock(&LOCK_open);
3325
3326
2/2
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 575536 times.
575619 if (view_open_result) return true;
3327
3328
3/4
✓ Branch 0 taken 575534 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 58 times.
✓ Branch 3 taken 575476 times.
575536 if (parse_view_definition(thd, table_list)) return true;
3329
3330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 575478 times.
575476 assert(table_list->is_view());
3331
3332 575478 return false;
3333 }
3334
3335 3689388 share_found:
3336
2/2
✓ Branch 0 taken 1138722 times.
✓ Branch 1 taken 3022178 times.
4160900 if (!(flags & MYSQL_OPEN_IGNORE_FLUSH)) {
3337
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1138702 times.
1138722 if (share->has_old_version()) {
3338 /*
3339 We already have an MDL lock. But we have encountered an old
3340 version of table in the table definition cache which is possible
3341 when someone changes the table version directly in the cache
3342 without acquiring a metadata lock (e.g. this can happen during
3343 "rolling" FLUSH TABLE(S)).
3344 Release our reference to share, wait until old version of
3345 share goes away and then try to get new version of table share.
3346 */
3347
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 release_table_share(share);
3348
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 mysql_mutex_unlock(&LOCK_open);
3349
3350 20 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
3351 bool wait_result;
3352
3353
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 thd->push_internal_handler(&mdl_deadlock_handler);
3354
3355 /*
3356 In case of deadlock we would like this thread to be preferred as
3357 a deadlock victim when this deadlock can be nicely handled by
3358 back-off and retry. We still have a few weird cases, like
3359 FLUSH TABLES <table-list> WITH READ LOCK, where we use strong
3360 metadata locks and open_tables() is called with some metadata
3361 locks pre-acquired. In these cases we still want to use DDL
3362 deadlock weight.
3363 */
3364 20 uint deadlock_weight = ot_ctx->can_back_off()
3365
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 8 times.
20 ? MDL_wait_for_subgraph::DEADLOCK_WEIGHT_DML
3366
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 : mdl_ticket->get_deadlock_weight();
3367
3368 wait_result =
3369
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 tdc_wait_for_old_version(thd, table_list->db, table_list->table_name,
3370 ot_ctx->get_timeout(), deadlock_weight);
3371
3372
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 thd->pop_internal_handler();
3373
3374
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
20 if (wait_result) return true;
3375
3376
2/4
✓ Branch 0 taken 18 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
18 DEBUG_SYNC(thd, "open_table_before_retry");
3377 18 goto retry_share;
3378
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
20 }
3379
3380
4/6
✓ Branch 0 taken 169640 times.
✓ Branch 1 taken 969062 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 169640 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1138702 times.
1308342 if (thd->open_tables &&
3381 169640 thd->open_tables->s->version() != share->version()) {
3382 /*
3383 If the version changes while we're opening the tables,
3384 we have to back off, close all the tables opened-so-far,
3385 and try to reopen them. Note: refresh_version is currently
3386 changed only during FLUSH TABLES.
3387 */
3388 release_table_share(share);
3389 mysql_mutex_unlock(&LOCK_open);
3390 (void)ot_ctx->request_backoff_action(Open_table_context::OT_REOPEN_TABLES,
3391 nullptr);
3392 return true;
3393 }
3394 }
3395
3396
1/2
✓ Branch 0 taken 4160880 times.
✗ Branch 1 not taken.
4160880 mysql_mutex_unlock(&LOCK_open);
3397
3398
3/4
✓ Branch 0 taken 4019535 times.
✓ Branch 1 taken 141345 times.
✓ Branch 2 taken 4019535 times.
✗ Branch 3 not taken.
4160880 DEBUG_SYNC(thd, "open_table_found_share");
3399
3400 8954695 if (table_list->mdl_request.type >= MDL_SHARED_WRITE &&
3401
2/2
✓ Branch 0 taken 584931 times.
✓ Branch 1 taken 48004 times.
632935 !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK)) &&
3402
6/8
✓ Branch 0 taken 632935 times.
✓ Branch 1 taken 3527945 times.
✓ Branch 2 taken 584931 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 584931 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 70959 times.
✓ Branch 7 taken 4089921 times.
5378746 share->db_type() &&
3403
3/4
✓ Branch 0 taken 584931 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70959 times.
✓ Branch 3 taken 513972 times.
584931 !(share->db_type()->flags & HTON_SUPPORTS_ONLINE_BACKUPS)) {
3404
2/4
✓ Branch 0 taken 70959 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 70959 times.
141918 if (thd->backup_tables_lock.abort_if_acquired() ||
3405
2/4
✓ Branch 0 taken 70959 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 70959 times.
70959 thd->backup_tables_lock.acquire_protection(thd, MDL_STATEMENT,
3406 ot_ctx->get_timeout()))
3407 goto err_lock;
3408
3409 70959 backup_protection_acquired = true;
3410 }
3411
3412 {
3413
1/2
✓ Branch 0 taken 4160880 times.
✗ Branch 1 not taken.
4160880 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
3414 4160880 const dd::Table *table_def = nullptr;
3415
2/2
✓ Branch 0 taken 4000030 times.
✓ Branch 1 taken 160850 times.
8160908 if (!(flags & MYSQL_OPEN_NO_NEW_TABLE_IN_SE) &&
3416
9/18
✓ Branch 0 taken 4000030 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4000030 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4000028 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4000028 times.
✓ Branch 8 taken 4000028 times.
✓ Branch 9 taken 160850 times.
✓ Branch 10 taken 4000030 times.
✓ Branch 11 taken 160850 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4160880 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
8160908 thd->dd_client()->acquire(share->db.str, share->table_name.str,
3417 &table_def)) {
3418 // Error is reported by the dictionary subsystem.
3419 goto err_lock;
3420 }
3421
3422
7/8
✓ Branch 0 taken 4000030 times.
✓ Branch 1 taken 160850 times.
✓ Branch 2 taken 4000026 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 4000021 times.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 4160871 times.
4160880 if (table_def && table_def->hidden() == dd::Abstract_table::HT_HIDDEN_SE) {
3423
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 my_error(ER_NO_SUCH_TABLE, MYF(0), table_list->db,
3424 table_list->table_name);
3425 5 goto err_lock;
3426 }
3427
3428 /* make a new table */
3429
2/4
✓ Branch 0 taken 4160873 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4160873 times.
4160871 if (!(table = (TABLE *)my_malloc(key_memory_TABLE, sizeof(*table),
3430 MYF(MY_WME))))
3431 goto err_lock;
3432
3433
1/2
✓ Branch 0 taken 4160820 times.
✗ Branch 1 not taken.
4160873 error = open_table_from_share(
3434 thd, share, alias,
3435
2/2
✓ Branch 0 taken 160850 times.
✓ Branch 1 taken 4000023 times.
4160873 ((flags & MYSQL_OPEN_NO_NEW_TABLE_IN_SE)
3436 ? 0
3437 : ((uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX |
3438 HA_TRY_READ_ONLY))),
3439 EXTRA_RECORD, thd->open_options, table, false, table_def);
3440
3441
2/2
✓ Branch 0 taken 248 times.
✓ Branch 1 taken 4160572 times.
4160820 if (error) {
3442 248 destroy(table);
3443
1/2
✓ Branch 0 taken 248 times.
✗ Branch 1 not taken.
248 my_free(table);
3444
3445
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 248 times.
248 if (error == 7)
3446 (void)ot_ctx->request_backoff_action(Open_table_context::OT_DISCOVER,
3447 table_list);
3448
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 229 times.
248 else if (error == 8)
3449
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 (void)ot_ctx->request_backoff_action(
3450 Open_table_context::OT_FIX_ROW_TYPE, table_list);
3451
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 224 times.
229 else if (share->crashed)
3452
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 (void)ot_ctx->request_backoff_action(Open_table_context::OT_REPAIR,
3453 table_list);
3454 248 goto err_lock;
3455
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4160572 times.
4160572 } else if (share->crashed) {
3456 switch (thd->lex->sql_command) {
3457 case SQLCOM_ALTER_TABLE:
3458 case SQLCOM_REPAIR:
3459 case SQLCOM_CHECK:
3460 case SQLCOM_SHOW_CREATE:
3461 break;
3462 default:
3463 closefrm(table, false);
3464 destroy(table);
3465 my_free(table);
3466 my_error(ER_CRASHED_ON_USAGE, MYF(0), share->table_name.str);
3467 goto err_lock;
3468 }
3469 }
3470
3471
2/4
✓ Branch 0 taken 4160591 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4160591 times.
4160572 if (open_table_entry_fini(thd, share, table_def, table)) {
3472 closefrm(table, false);
3473 destroy(table);
3474 my_free(table);
3475 goto err_lock;
3476 }
3477
2/2
✓ Branch 0 taken 4160619 times.
✓ Branch 1 taken 252 times.
4160844 }
3478 {
3479 /* Add new TABLE object to table cache for this connection. */
3480 4160619 Table_cache *tc = table_cache_manager.get_cache(thd);
3481
3482
1/2
✓ Branch 0 taken 4160616 times.
✗ Branch 1 not taken.
4160616 tc->lock();
3483
3484
2/4
✓ Branch 0 taken 4160612 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4160612 times.
4160616 if (tc->add_used_table(thd, table)) {
3485 tc->unlock();
3486 goto err_lock;
3487 }
3488
1/2
✓ Branch 0 taken 4160622 times.
✗ Branch 1 not taken.
4160612 tc->unlock();
3489 }
3490 4160622 thd->status_var.table_open_cache_misses++;
3491
3492 106652238 table_found:
3493
3494 319885585 if (!backup_protection_acquired &&
3495
2/2
✓ Branch 0 taken 27001631 times.
✓ Branch 1 taken 79579434 times.
106581065 table_list->mdl_request.type >= MDL_SHARED_WRITE &&
3496
2/2
✓ Branch 0 taken 26398754 times.
✓ Branch 1 taken 602877 times.
27001631 !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK)) &&
3497
6/8
✓ Branch 0 taken 106581065 times.
✓ Branch 1 taken 71173 times.
✓ Branch 2 taken 26398786 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 26398832 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 422904 times.
✓ Branch 7 taken 106229378 times.
239632147 share->db_type() &&
3498
3/4
✓ Branch 0 taken 26398844 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 422905 times.
✓ Branch 3 taken 25975939 times.
26398832 !(share->db_type()->flags & HTON_SUPPORTS_ONLINE_BACKUPS)) {
3499
2/4
✓ Branch 0 taken 422884 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 423001 times.
845916 if (thd->backup_tables_lock.abort_if_acquired() ||
3500
3/4
✓ Branch 0 taken 423012 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 423001 times.
422884 thd->backup_tables_lock.acquire_protection(thd, MDL_STATEMENT,
3501 ot_ctx->get_timeout())) {
3502 Table_cache *tc = table_cache_manager.get_cache(thd);
3503
3504 tc->lock();
3505
3506 tc->release_table(thd, table);
3507
3508 tc->unlock();
3509
3510 table->file->unbind_psi();
3511
3512 return true;
3513 }
3514 }
3515
3516 106652379 table->mdl_ticket = mdl_ticket;
3517
3518 106652379 table->next = thd->open_tables; /* Link into simple list */
3519
1/2
✓ Branch 0 taken 106652050 times.
✗ Branch 1 not taken.
106652379 thd->set_open_tables(table);
3520
3521 106652050 table->reginfo.lock_type = TL_READ; /* Assume read */
3522
3523 106709374 reset:
3524
1/2
✓ Branch 0 taken 106708448 times.
✗ Branch 1 not taken.
106709374 table->reset();
3525
1/2
✓ Branch 0 taken 106708721 times.
✗ Branch 1 not taken.
106708448 table->set_created();
3526 /*
3527 Check that there is no reference to a condition from an earlier query
3528 (cf. Bug#58553).
3529 */
3530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106708721 times.
106708721 assert(table->file->pushed_cond == nullptr);
3531
3532 // Table is not a derived table and not a non-updatable view:
3533 106708721 table_list->set_updatable();
3534 106708542 table_list->set_insertable();
3535
3536 106708947 table_list->table = table;
3537
3538 /*
3539 Position for each partition in the bitmap is read from the Handler_share
3540 instance of the table. In MYSQL_OPEN_NO_NEW_TABLE_IN_SE mode, table is not
3541 opened in the SE and Handler_share instance for it is not created. Hence
3542 skipping partitions bitmap setting in the MYSQL_OPEN_NO_NEW_TABLE_IN_SE
3543 mode.
3544 */
3545
2/2
✓ Branch 0 taken 106532098 times.
✓ Branch 1 taken 176849 times.
106708947 if (!(flags & MYSQL_OPEN_NO_NEW_TABLE_IN_SE)) {
3546
2/2
✓ Branch 0 taken 327943 times.
✓ Branch 1 taken 106204155 times.
106532098 if (table->part_info) {
3547 /* Set all [named] partitions as used. */
3548
3/4
✓ Branch 0 taken 327945 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 327939 times.
327943 if (table->part_info->set_partition_bitmaps(table_list)) return true;
3549
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 106204154 times.
106204155 } else if (table_list->partition_names) {
3550 /* Don't allow PARTITION () clause on a nonpartitioned table */
3551
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
3552 1 return true;
3553 }
3554 }
3555
3556
1/2
✓ Branch 0 taken 106709459 times.
✗ Branch 1 not taken.
106708942 table->init(thd, table_list);
3557
3558 /* Request a read lock for implicitly opened P_S tables. */
3559
8/8
✓ Branch 0 taken 79856 times.
✓ Branch 1 taken 106629564 times.
✓ Branch 2 taken 75179 times.
✓ Branch 3 taken 4677 times.
✓ Branch 4 taken 823 times.
✓ Branch 5 taken 74398 times.
✓ Branch 6 taken 823 times.
✓ Branch 7 taken 106708639 times.
106784680 if (in_LTM(thd) && table_list->table->file->get_lock_type() == F_UNLCK &&
3560 75179 belongs_to_p_s(table_list)) {
3561
1/2
✓ Branch 0 taken 573 times.
✗ Branch 1 not taken.
823 table_list->table->file->ha_external_lock(thd, F_RDLCK);
3562 }
3563
3564 106709212 return false;
3565
3566 252 err_lock:
3567
1/2
✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
252 mysql_mutex_lock(&LOCK_open);
3568
1/2
✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
253 release_table_share(share);
3569
1/2
✓ Branch 0 taken 253 times.
✗ Branch 1 not taken.
253 mysql_mutex_unlock(&LOCK_open);
3570
3571 253 return true;
3572 107937368 }
3573
3574 /**
3575 Find table in the list of open tables.
3576
3577 @param list List of TABLE objects to be inspected.
3578 @param db Database name
3579 @param table_name Table name
3580
3581 @return Pointer to the TABLE object found, 0 if no table found.
3582 */
3583
3584 1512 TABLE *find_locked_table(TABLE *list, const char *db, const char *table_name) {
3585 char key[MAX_DBKEY_LENGTH];
3586
1/2
✓ Branch 0 taken 1512 times.
✗ Branch 1 not taken.
1512 size_t key_length = create_table_def_key(db, table_name, key);
3587
3588
2/2
✓ Branch 0 taken 1612 times.
✓ Branch 1 taken 35 times.
1647 for (TABLE *table = list; table; table = table->next) {
3589
2/2
✓ Branch 0 taken 1568 times.
✓ Branch 1 taken 44 times.
1612 if (table->s->table_cache_key.length == key_length &&
3590
2/2
✓ Branch 0 taken 1477 times.
✓ Branch 1 taken 91 times.
1568 !memcmp(table->s->table_cache_key.str, key, key_length))
3591 1477 return table;
3592 }
3593 35 return (nullptr);
3594 }
3595
3596 /**
3597 Find instance of TABLE with upgradable or exclusive metadata
3598 lock from the list of open tables, emit error if no such table
3599 found.
3600
3601 @param thd Thread context
3602 @param db Database name.
3603 @param table_name Name of table.
3604 @param no_error Don't emit error if no suitable TABLE
3605 instance were found.
3606
3607 @note This function checks if the connection holds a global IX
3608 metadata lock. If no such lock is found, it is not safe to
3609 upgrade the lock and ER_TABLE_NOT_LOCKED_FOR_WRITE will be
3610 reported.
3611
3612 @return Pointer to TABLE instance with MDL_SHARED_UPGRADABLE
3613 MDL_SHARED_NO_WRITE, MDL_SHARED_NO_READ_WRITE, or
3614 MDL_EXCLUSIVE metadata lock, NULL otherwise.
3615 */
3616
3617 1496 TABLE *find_table_for_mdl_upgrade(THD *thd, const char *db,
3618 const char *table_name, bool no_error) {
3619 1496 TABLE *tab = find_locked_table(thd->open_tables, db, table_name);
3620
3621
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 1476 times.
1496 if (!tab) {
3622
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (!no_error) my_error(ER_TABLE_NOT_LOCKED, MYF(0), table_name);
3623 20 return nullptr;
3624 }
3625
3626 /*
3627 It is not safe to upgrade the metadata lock without a global IX lock.
3628 This can happen with FLUSH TABLES <list> WITH READ LOCK as we in these
3629 cases don't take a global IX lock in order to be compatible with
3630 global read lock.
3631 */
3632
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 1454 times.
1476 if (!thd->mdl_context.owns_equal_or_stronger_lock(MDL_key::GLOBAL, "", "",
3633 MDL_INTENTION_EXCLUSIVE)) {
3634
1/2
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
22 if (!no_error) my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name);
3635 22 return nullptr;
3636 }
3637
3638 1454 while (tab->mdl_ticket != nullptr &&
3639
4/6
✓ Branch 0 taken 1454 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 1440 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1454 times.
1468 !tab->mdl_ticket->is_upgradable_or_exclusive() &&
3640
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 (tab = find_locked_table(tab->next, db, table_name)))
3641 continue;
3642
3643
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 1440 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
1454 if (!tab && !no_error)
3644 14 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_name);
3645
3646 1454 return tab;
3647 }
3648
3649 /*
3650 Function to assign a new table map id to a table share.
3651
3652 PARAMETERS
3653
3654 share - Pointer to table share structure
3655
3656 DESCRIPTION
3657
3658 We are intentionally not checking that share->mutex is locked
3659 since this function should only be called when opening a table
3660 share and before it is entered into the table_def_cache (meaning
3661 that it cannot be fetched by another thread, even accidentally).
3662
3663 PRE-CONDITION(S)
3664
3665 share is non-NULL
3666 The LOCK_open mutex is locked.
3667
3668 POST-CONDITION(S)
3669
3670 share->table_map_id is given a value that with a high certainty is
3671 not used by any other table (the only case where a table id can be
3672 reused is on wrap-around, which means more than 2^48 table
3673 share opens have been executed while one table was open all the
3674 time).
3675
3676 */
3677 static Table_id last_table_id;
3678
3679 2126236 void assign_new_table_id(TABLE_SHARE *share) {
3680
1/2
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
2126236 DBUG_TRACE;
3681
3682 /* Preconditions */
3683
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2126236 times.
2126236 assert(share != nullptr);
3684 mysql_mutex_assert_owner(&LOCK_open);
3685
3686
3/4
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 2126217 times.
2126236 DBUG_EXECUTE_IF("dbug_table_map_id_500", last_table_id = 500;);
3687
3/4
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2126235 times.
2126236 DBUG_EXECUTE_IF("dbug_table_map_id_4B_UINT_MAX+501",
3688 last_table_id = 501ULL + UINT_MAX;);
3689
3/4
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2126235 times.
2126236 DBUG_EXECUTE_IF("dbug_table_map_id_6B_UINT_MAX",
3690 last_table_id = (~0ULL >> 16););
3691
3692 2126236 share->table_map_id = last_table_id++;
3693
5/8
✓ Branch 0 taken 2126236 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2126236 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 72 times.
✓ Branch 5 taken 2126164 times.
✓ Branch 6 taken 72 times.
✗ Branch 7 not taken.
2126236 DBUG_PRINT("info", ("table_id=%llu", share->table_map_id.id()));
3694 2126236 }
3695
3696 /**
3697 Compare metadata versions of an element obtained from the table
3698 definition cache and its corresponding node in the parse tree.
3699
3700 @details If the new and the old values mismatch, invoke
3701 Metadata_version_observer.
3702 At prepared statement prepare, all TABLE_LIST version values are
3703 NULL and we always have a mismatch. But there is no observer set
3704 in THD, and therefore no error is reported. Instead, we update
3705 the value in the parse tree, effectively recording the original
3706 version.
3707 At prepared statement execute, an observer may be installed. If
3708 there is a version mismatch, we push an error and return true.
3709
3710 For conventional execution (no prepared statements), the
3711 observer is never installed.
3712
3713 @sa Execute_observer
3714 @sa check_prepared_statement() to see cases when an observer is installed
3715 @sa TABLE_LIST::is_table_ref_id_equal()
3716 @sa TABLE_SHARE::get_table_ref_id()
3717
3718 @param[in] thd used to report errors
3719 @param[in,out] tables TABLE_LIST instance created by the parser
3720 Metadata version information in this object
3721 is updated upon success.
3722 @param[in] table_share an element from the table definition cache
3723
3724 @retval true an error, which has been reported
3725 @retval false success, version in TABLE_LIST has been updated
3726 */
3727
3728 107541933 static bool check_and_update_table_version(THD *thd, TABLE_LIST *tables,
3729 TABLE_SHARE *table_share) {
3730
2/2
✓ Branch 0 taken 103759485 times.
✓ Branch 1 taken 3783191 times.
107541933 if (!tables->is_table_ref_id_equal(table_share)) {
3731 /*
3732 Version of the table share is different from the
3733 previous execution of the prepared statement, and it is
3734 unacceptable for this SQLCOM.
3735 */
3736
2/2
✓ Branch 0 taken 37699 times.
✓ Branch 1 taken 103721926 times.
103759485 if (ask_to_reprepare(thd)) return true;
3737 /* Always maintain the latest version and type */
3738 103721926 tables->set_table_ref_id(table_share);
3739 }
3740 107505284 return false;
3741 }
3742
3743 /**
3744 Compares versions of a stored routine obtained from the sp cache
3745 and the version used at prepare.
3746
3747 @details If the new and the old values mismatch, invoke
3748 Metadata_version_observer.
3749 At prepared statement prepare, all Sroutine_hash_entry version values
3750 are NULL and we always have a mismatch. But there is no observer set
3751 in THD, and therefore no error is reported. Instead, we update
3752 the value in Sroutine_hash_entry, effectively recording the original
3753 version.
3754 At prepared statement execute, an observer may be installed. If
3755 there is a version mismatch, we push an error and return true.
3756
3757 For conventional execution (no prepared statements), the
3758 observer is never installed.
3759
3760 @param[in] thd used to report errors
3761 @param[in,out] rt pointer to stored routine entry in the
3762 parse tree
3763 @param[in] sp pointer to stored routine cache entry.
3764 Can be NULL if there is no such routine.
3765 @retval true an error, which has been reported
3766 @retval false success, version in Sroutine_hash_entry has been updated
3767 */
3768
3769 115941 static bool check_and_update_routine_version(THD *thd, Sroutine_hash_entry *rt,
3770 sp_head *sp) {
3771 115941 int64 spc_version = sp_cache_version();
3772 /* sp is NULL if there is no such routine. */
3773
2/2
✓ Branch 0 taken 115836 times.
✓ Branch 1 taken 105 times.
115941 int64 version = sp ? sp->sp_cache_version() : spc_version;
3774 /*
3775 If the version in the parse tree is stale,
3776 or the version in the cache is stale and sp is not used,
3777 we need to reprepare.
3778 Sic: version != spc_version <--> sp is not NULL.
3779 */
3780
6/6
✓ Branch 0 taken 37472 times.
✓ Branch 1 taken 78469 times.
✓ Branch 2 taken 108 times.
✓ Branch 3 taken 37364 times.
✓ Branch 4 taken 78576 times.
✓ Branch 5 taken 37365 times.
116049 if (rt->m_cache_version != version ||
3781
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 1 times.
108 (version != spc_version && !sp->is_invoked())) {
3782 /*
3783 Version of the sp cache is different from the
3784 previous execution of the prepared statement, and it is
3785 unacceptable for this SQLCOM.
3786 */
3787
2/2
✓ Branch 0 taken 119 times.
✓ Branch 1 taken 78457 times.
78576 if (ask_to_reprepare(thd)) return true;
3788 /* Always maintain the latest cache version. */
3789 78457 rt->m_cache_version = version;
3790 }
3791 115822 return false;
3792 }
3793
3794 /**
3795 Open view by getting its definition from disk (and table cache in future).
3796
3797 @param thd Thread handle
3798 @param table_list TABLE_LIST with db, table_name & belong_to_view
3799 @param cache_key Key for table definition cache
3800 @param cache_key_length Length of cache_key
3801
3802 @todo This function is needed for special handling of views under
3803 LOCK TABLES. We probably should get rid of it in long term.
3804
3805 @return false if success, true - otherwise.
3806 */
3807
3808 537 static bool tdc_open_view(THD *thd, TABLE_LIST *table_list,
3809 const char *cache_key, size_t cache_key_length) {
3810 TABLE_SHARE *share;
3811
3812 537 mysql_mutex_lock(&LOCK_open);
3813
3814
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 537 times.
537 if (!(share = get_table_share(thd, table_list->db, table_list->table_name,
3815 cache_key, cache_key_length, true))) {
3816 mysql_mutex_unlock(&LOCK_open);
3817 return true;
3818 }
3819
3820 /*
3821 Check TABLE_SHARE-version of view only if we have been instructed to do
3822 so. We do not need to check the version if we're executing CREATE VIEW or
3823 ALTER VIEW statements.
3824
3825 In the future, this functionality should be moved out from
3826 tdc_open_view(), and tdc_open_view() should became a part of a clean
3827 table-definition-cache interface.
3828 */
3829
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 530 times.
537 if (check_and_update_table_version(thd, table_list, share)) {
3830 7 release_table_share(share);
3831 7 mysql_mutex_unlock(&LOCK_open);
3832 7 return true;
3833 }
3834
3835
1/2
✓ Branch 0 taken 530 times.
✗ Branch 1 not taken.
530 if (share->is_view) {
3836 530 bool view_open_result = open_and_read_view(thd, share, table_list);
3837
3838 530 release_table_share(share);
3839 530 mysql_mutex_unlock(&LOCK_open);
3840
3841
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 530 times.
530 if (view_open_result) return true;
3842
3843 530 return parse_view_definition(thd, table_list);
3844 }
3845
3846 my_error(ER_WRONG_OBJECT, MYF(0), share->db.str, share->table_name.str,
3847 "VIEW");
3848 release_table_share(share);
3849 mysql_mutex_unlock(&LOCK_open);
3850 return true;
3851 }
3852
3853 /**
3854 Finalize the process of TABLE creation by loading table triggers
3855 and taking action if a HEAP table content was emptied implicitly.
3856 */
3857
3858 4160614 static bool open_table_entry_fini(THD *thd, TABLE_SHARE *share,
3859 const dd::Table *table, TABLE *entry) {
3860
6/6
✓ Branch 0 taken 3999764 times.
✓ Branch 1 taken 160850 times.
✓ Branch 2 taken 41116 times.
✓ Branch 3 taken 3958638 times.
✓ Branch 4 taken 41116 times.
✓ Branch 5 taken 4119488 times.
4160614 if (table != nullptr && table->has_trigger()) {
3861 41116 Table_trigger_dispatcher *d = Table_trigger_dispatcher::create(entry);
3862
3863
3/6
✓ Branch 0 taken 41116 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 41115 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 41115 times.
41116 if (!d || d->check_n_load(thd, *table)) {
3864 destroy(d);
3865 return true;
3866 }
3867
3868 41115 entry->triggers = d;
3869 }
3870
3871 /*
3872 If we are here, there was no fatal error (but error may be still
3873 uninitialized).
3874
3875 Ignore handling implicit_emptied property (which is only for heap
3876 tables) when I_S query is opening this table to read table statistics.
3877 The reason for avoiding this is that the
3878 mysql_bin_log.write_dml_directly() invokes a commit(). And this commit
3879 is not expected to be invoked when fetching I_S table statistics.
3880 */
3881
4/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 4160546 times.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 4160547 times.
4160666 if (unlikely(entry->file->implicit_emptied) &&
3882
3/4
✓ Branch 0 taken 63 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 62 times.
✓ Branch 3 taken 1 times.
63 (!thd->lex || !thd->lex->m_IS_table_stats.is_reading_stats_by_open())) {
3883 62 entry->file->implicit_emptied = false;
3884
1/2
✓ Branch 0 taken 71 times.
✗ Branch 1 not taken.
62 if (mysql_bin_log.is_open()) {
3885 71 bool result = false;
3886 71 String temp_buf;
3887
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 result = temp_buf.append("TRUNCATE TABLE ");
3888
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 append_identifier(thd, &temp_buf, share->db.str, strlen(share->db.str));
3889
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 result = temp_buf.append(".");
3890
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 append_identifier(thd, &temp_buf, share->table_name.str,
3891 strlen(share->table_name.str));
3892
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 result = temp_buf.append(
3893 " /* generated by server, implicitly emptying in-memory table */");
3894
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 56 times.
56 if (result) {
3895 /*
3896 As replication is maybe going to be corrupted, we need to warn the
3897 DBA on top of warning the client (which will automatically be done
3898 because of MYF(MY_WME) in my_malloc() above).
3899 */
3900 LogErr(ERROR_LEVEL,
3901 ER_BINLOG_OOM_WRITING_DELETE_WHILE_OPENING_HEAP_TABLE,
3902 share->db.str, share->table_name.str);
3903 destroy(entry->triggers);
3904 return true;
3905 }
3906 /*
3907 Create a new THD object for binary logging the statement which
3908 implicitly empties the in-memory table.
3909 */
3910
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 THD new_thd;
3911 56 new_thd.thread_stack = (char *)&thd;
3912
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.set_new_thread_id();
3913
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.store_globals();
3914
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.set_db(thd->db());
3915 56 new_thd.variables.gtid_next.set_automatic();
3916 56 Global_THD_manager *thd_manager = Global_THD_manager::get_instance();
3917
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 thd_manager->add_thd(&new_thd);
3918 56 result = mysql_bin_log.write_stmt_directly(
3919
2/4
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56 times.
✗ Branch 3 not taken.
56 &new_thd, temp_buf.c_ptr_safe(), temp_buf.length(), SQLCOM_TRUNCATE);
3920
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.restore_globals();
3921
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 thd->store_globals();
3922
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 new_thd.release_resources();
3923
1/2
✓ Branch 0 taken 56 times.
✗ Branch 1 not taken.
56 thd_manager->remove_thd(&new_thd);
3924 56 return result;
3925 56 }
3926 }
3927 4160538 return false;
3928 }
3929
3930 /**
3931 Auxiliary routine which is used for performing automatic table repair.
3932 */
3933
3934 4 static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) {
3935 const char *cache_key;
3936 size_t cache_key_length;
3937 TABLE_SHARE *share;
3938 TABLE *entry;
3939 4 bool result = true;
3940
3941
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 cache_key_length = get_table_def_key(table_list, &cache_key);
3942
3943
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 thd->clear_error();
3944
3945
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 mysql_mutex_lock(&LOCK_open);
3946
3947
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 if (!(share = get_table_share(thd, table_list->db, table_list->table_name,
3948 cache_key, cache_key_length, true)))
3949 goto end_unlock;
3950
3951
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (share->is_view) {
3952 release_table_share(share);
3953 goto end_unlock;
3954 }
3955
3956 4 if (!(entry =
3957
2/4
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
4 (TABLE *)my_malloc(key_memory_TABLE, sizeof(TABLE), MYF(MY_WME)))) {
3958 release_table_share(share);
3959 goto end_unlock;
3960 }
3961
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 mysql_mutex_unlock(&LOCK_open);
3962
3963
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (open_table_from_share(thd, share, table_list->alias,
3964 (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
3965 HA_GET_INDEX | HA_TRY_READ_ONLY),
3966 EXTRA_RECORD, ha_open_options | HA_OPEN_FOR_REPAIR,
3967 4 entry, false, nullptr) ||
3968
3/6
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 4 times.
8 !entry->file ||
3969
4/8
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 4 times.
4 (entry->file->is_crashed() && entry->file->ha_check_and_repair(thd))) {
3970 /* Give right error message */
3971 thd->clear_error();
3972 my_error(ER_NOT_KEYFILE, MYF(0), share->table_name.str);
3973 LogErr(ERROR_LEVEL, ER_FAILED_TO_REPAIR_TABLE, share->db.str,
3974 share->table_name.str);
3975 if (entry->file) closefrm(entry, false);
3976 } else {
3977
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 thd->clear_error(); // Clear error message
3978
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 closefrm(entry, false);
3979 4 result = false;
3980 }
3981
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_free(entry);
3982
3983
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 table_cache_manager.lock_all_and_tdc();
3984
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 release_table_share(share);
3985 /* Remove the repaired share from the table cache. */
3986
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
3987 table_list->table_name, true);
3988
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 table_cache_manager.unlock_all_and_tdc();
3989 4 return result;
3990 end_unlock:
3991 mysql_mutex_unlock(&LOCK_open);
3992 return result;
3993 }
3994
3995 /**
3996 Error handler class for suppressing HA_ERR_ROW_FORMAT_CHANGED errors from SE.
3997 */
3998
3999 class Fix_row_type_error_handler : public Internal_error_handler {
4000 public:
4001 17 bool handle_condition(THD *, uint sql_errno, const char *,
4002 Sql_condition::enum_severity_level *,
4003 const char *) override {
4004
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 return sql_errno == ER_GET_ERRNO && my_errno() == HA_ERR_ROW_FORMAT_CHANGED;
4005 }
4006 };
4007
4008 /**
4009 Auxiliary routine for automatically updating row format for the table.
4010 */
4011
4012 17 static bool fix_row_type(THD *thd, TABLE_LIST *table_list) {
4013 const char *cache_key;
4014
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 size_t cache_key_length = get_table_def_key(table_list, &cache_key);
4015
4016
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 thd->clear_error();
4017
4018 TABLE_SHARE *share;
4019
4020 {
4021 /*
4022 Hold LOCK_open until we can keep it and are likely to
4023 release TABLE_SHARE on return.
4024 */
4025 17 MUTEX_LOCK(lock_open_guard, &LOCK_open);
4026
4027 17 No_such_table_error_handler no_such_table_handler;
4028
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 thd->push_internal_handler(&no_such_table_handler);
4029
4030
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 share = get_table_share(thd, table_list->db, table_list->table_name,
4031 cache_key, cache_key_length, true);
4032
4033
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 thd->pop_internal_handler();
4034
4035
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (!share) {
4036 /*
4037 Somebody managed to drop table after we have performed back-off
4038 before trying to fix row format for the table. Such situation is
4039 quite unlikely but theoretically possible. Do not report error
4040 (silence it using error handler), let the caller try to reopen
4041 tables and handle missing table in appropriate way (e.g. ignore
4042 this fact it if the table comes from prelocking list).
4043 */
4044 if (no_such_table_handler.safely_trapped_errors()) return false;
4045
4046 return true;
4047 }
4048
4049
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (share->is_view) {
4050 /*
4051 Somebody managed to replace our table with a view after we
4052 have performed back-off before trying to fix row format for
4053 the table. Such situation is quite unlikely but is OK.
4054 Do not report error, let the caller try to reopen tables.
4055 */
4056 release_table_share(share);
4057 return false;
4058 }
4059
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 }
4060
4061 17 int error = 0;
4062
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 dd::cache::Dictionary_client::Auto_releaser releaser(thd->dd_client());
4063 17 dd::Table *table_def = nullptr;
4064
4/8
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 17 times.
17 if (thd->dd_client()->acquire_for_modification(
4065 share->db.str, share->table_name.str, &table_def))
4066 error = 1;
4067
4068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 assert(table_def != nullptr);
4069
4070 /*
4071 Silence expected HA_ERR_ROW_FORMAT_CHANGED errors.
4072 */
4073 17 Fix_row_type_error_handler err_handler;
4074
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 thd->push_internal_handler(&err_handler);
4075
4076
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 TABLE tmp_table;
4077
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if (error == 0)
4078
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 error = open_table_from_share(thd, share, table_list->alias,
4079 (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE |
4080 HA_GET_INDEX | HA_TRY_READ_ONLY),
4081 EXTRA_RECORD, ha_open_options, &tmp_table,
4082 false, table_def);
4083
4084
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 thd->pop_internal_handler();
4085
4086
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if (error == 8) {
4087 17 Disable_autocommit_guard autocommit_guard(thd);
4088
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 HA_CREATE_INFO create_info;
4089 17 create_info.row_type = share->row_type;
4090 17 create_info.table_options = share->db_options_in_use;
4091
4092
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 handler *file = get_new_handler(share, share->m_part_info != nullptr,
4093 thd->mem_root, share->db_type());
4094
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if (file != nullptr) {
4095
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 row_type correct_row_type = file->get_real_row_type(&create_info);
4096
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 bool result = dd::fix_row_type(thd, table_def, correct_row_type);
4097 17 destroy(file);
4098
4099
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (result) {
4100 trans_rollback_stmt(thd);
4101 trans_rollback(thd);
4102 } else {
4103
4/8
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 17 times.
17 result = trans_commit_stmt(thd) || trans_commit(thd);
4104
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 if (!result) error = 0;
4105 }
4106 }
4107
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
17 } else if (error == 0)
4108 closefrm(&tmp_table, false);
4109
4110
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 table_cache_manager.lock_all_and_tdc();
4111
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 release_table_share(share);
4112 /*
4113 Remove the share from the table cache. So attempt to reopen table
4114 will construct its new version with correct real_row_type value.
4115 */
4116
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
4117 table_list->table_name, true);
4118
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 table_cache_manager.unlock_all_and_tdc();
4119 17 return error != 0;
4120 17 }
4121
4122 /** Open_table_context */
4123
4124 50902495 Open_table_context::Open_table_context(THD *thd, uint flags)
4125 50902495 : m_thd(thd),
4126 50902495 m_failed_table(nullptr),
4127 50902495 m_start_of_statement_svp(thd->mdl_context.mdl_savepoint()),
4128 101809128 m_timeout(flags & MYSQL_LOCK_IGNORE_TIMEOUT
4129
2/2
✓ Branch 0 taken 29055740 times.
✓ Branch 1 taken 21848824 times.
50904564 ? LONG_TIMEOUT
4130 29055740 : thd->variables.lock_wait_timeout),
4131 50904564 m_flags(flags),
4132 50904564 m_action(OT_NO_ACTION),
4133 50904564 m_has_locks(thd->mdl_context.has_locks()),
4134 50904623 m_has_protection_against_grl(false) {}
4135
4136 /**
4137 Check if we can back-off and set back off action if we can.
4138 Otherwise report and return error.
4139
4140 @retval true if back-off is impossible.
4141 @retval false if we can back off. Back off action has been set.
4142 */
4143
4144 58 bool Open_table_context::request_backoff_action(
4145 enum_open_table_action action_arg, TABLE_LIST *table) {
4146 /*
4147 A back off action may be one of four kinds:
4148
4149 * We met a broken table that needs repair, or a table that
4150 is not present on this MySQL server and needs re-discovery.
4151 To perform the action, we need an exclusive metadata lock on
4152 the table. Acquiring X lock while holding other shared
4153 locks can easily lead to deadlocks. We rely on MDL deadlock
4154 detector to discover them. If this is a multi-statement
4155 transaction that holds metadata locks for completed statements,
4156 we should keep these locks after discovery/repair.
4157 The action type in this case is OT_DISCOVER or OT_REPAIR.
4158 * We met a table that has outdated value in ROW_FORMAT column
4159 in the data-dictionary/value of TABLE_SHARE::real_row_type
4160 attribute, which need to be updated. To update the
4161 data-dictionary we not only need to acquire X lock on the
4162 table, but also need to commit the transaction. If there
4163 is an ongoing transaction (and some metadata locks acquired)
4164 we cannot proceed and report an error. The action type for
4165 this case is OT_FIX_ROW_TYPE.
4166 * Our attempt to acquire an MDL lock lead to a deadlock,
4167 detected by the MDL deadlock detector. The current
4168 session was chosen a victim. If this is a multi-statement
4169 transaction that holds metadata locks taken by completed
4170 statements, restarting locking for the current statement
4171 may lead to a livelock. Releasing locks of completed
4172 statements can not be done as will lead to violation
4173 of ACID. Thus, again, if m_has_locks is set,
4174 we report an error. Otherwise, when there are no metadata
4175 locks other than which belong to this statement, we can
4176 try to recover from error by releasing all locks and
4177 restarting the pre-locking.
4178 Similarly, a deadlock error can occur when the
4179 pre-locking process met a TABLE_SHARE that is being
4180 flushed, and unsuccessfully waited for the flush to
4181 complete. A deadlock in this case can happen, e.g.,
4182 when our session is holding a metadata lock that
4183 is being waited on by a session which is using
4184 the table which is being flushed. The only way
4185 to recover from this error is, again, to close all
4186 open tables, release all locks, and retry pre-locking.
4187 Action type name is OT_REOPEN_TABLES. Re-trying
4188 while holding some locks may lead to a livelock,
4189 and thus we don't do it.
4190 * Finally, this session has open TABLEs from different
4191 "generations" of the table cache. This can happen, e.g.,
4192 when, after this session has successfully opened one
4193 table used for a statement, FLUSH TABLES interfered and
4194 expelled another table used in it. FLUSH TABLES then
4195 blocks and waits on the table already opened by this
4196 statement.
4197 We detect this situation by ensuring that table cache
4198 version of all tables used in a statement is the same.
4199 If it isn't, all tables needs to be reopened.
4200 Note, that we can always perform a reopen in this case,
4201 even if we already have metadata locks, since we don't
4202 keep tables open between statements and a livelock
4203 is not possible.
4204 */
4205
6/6
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 34 times.
✓ Branch 2 taken 19 times.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 23 times.
✓ Branch 5 taken 35 times.
111 if ((action_arg == OT_BACKOFF_AND_RETRY || action_arg == OT_FIX_ROW_TYPE) &&
4206
3/4
✓ Branch 0 taken 53 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✓ Branch 3 taken 30 times.
53 (has_commit_order_manager(m_thd) || m_has_locks)) {
4207 23 my_error(ER_LOCK_DEADLOCK, MYF(0));
4208 23 m_thd->mark_transaction_to_rollback(true);
4209 23 return true;
4210 }
4211 /*
4212 If auto-repair or discovery are requested, a pointer to table
4213 list element must be provided.
4214 */
4215
2/2
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 13 times.
35 if (table) {
4216
4/6
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 5 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 17 times.
22 assert(action_arg == OT_DISCOVER || action_arg == OT_REPAIR ||
4217 action_arg == OT_FIX_ROW_TYPE);
4218 44 m_failed_table = new (m_thd->mem_root)
4219 TABLE_LIST(table->db, table->db_length, table->table_name,
4220
2/4
✓ Branch 0 taken 22 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 22 times.
✗ Branch 3 not taken.
22 table->table_name_length, table->alias, TL_WRITE);
4221
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 if (m_failed_table == nullptr) return true;
4222 22 m_failed_table->mdl_request.set_type(MDL_EXCLUSIVE);
4223 }
4224 35 m_action = action_arg;
4225 35 return false;
4226 }
4227
4228 /**
4229 An error handler to mark transaction to rollback on DEADLOCK error
4230 during DISCOVER / REPAIR.
4231 */
4232 class MDL_deadlock_discovery_repair_handler : public Internal_error_handler {
4233 public:
4234 4 bool handle_condition(THD *thd, uint sql_errno, const char *,
4235 Sql_condition::enum_severity_level *,
4236 const char *) override {
4237
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 3 times.
4 if (sql_errno == ER_LOCK_DEADLOCK) {
4238 1 thd->mark_transaction_to_rollback(true);
4239 }
4240 /*
4241 We have marked this transaction to rollback. Return false to allow
4242 error to be reported or handled by other handlers.
4243 */
4244 4 return false;
4245 }
4246 };
4247
4248 /**
4249 Recover from failed attempt of open table by performing requested action.
4250
4251 @pre This function should be called only with "action" != OT_NO_ACTION
4252 and after having called @sa close_tables_for_reopen().
4253
4254 @retval false - Success. One should try to open tables once again.
4255 @retval true - Error
4256 */
4257
4258 35 bool Open_table_context::recover_from_failed_open() {
4259
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 30 times.
35 if (m_action == OT_REPAIR) {
4260
2/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5 DEBUG_SYNC(m_thd, "recover_ot_repair");
4261 }
4262
4263 /*
4264 Skip repair and discovery in IS-queries as they require X lock
4265 which could lead to delays or deadlock. Instead set
4266 ER_WARN_I_S_SKIPPED_TABLE which will be converted to a warning
4267 later.
4268 */
4269
3/4
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 30 times.
✗ Branch 3 not taken.
35 if ((m_action == OT_REPAIR || m_action == OT_DISCOVER ||
4270
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13 times.
30 m_action == OT_FIX_ROW_TYPE) &&
4271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 22 times.
22 (m_flags & MYSQL_OPEN_FAIL_ON_MDL_CONFLICT)) {
4272 my_error(ER_WARN_I_S_SKIPPED_TABLE, MYF(0),
4273 m_failed_table->mdl_request.key.db_name(),
4274 m_failed_table->mdl_request.key.name());
4275 return true;
4276 }
4277
4278 35 bool result = false;
4279 35 MDL_deadlock_discovery_repair_handler handler;
4280 /*
4281 Install error handler to mark transaction to rollback on DEADLOCK error.
4282 */
4283
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 m_thd->push_internal_handler(&handler);
4284
4285 /* Execute the action. */
4286
3/6
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 17 times.
✗ Branch 5 not taken.
35 switch (m_action) {
4287 13 case OT_BACKOFF_AND_RETRY:
4288 13 break;
4289 case OT_REOPEN_TABLES:
4290 break;
4291 case OT_DISCOVER: {
4292 if ((result = lock_table_names(m_thd, m_failed_table, nullptr,
4293 get_timeout(), 0)))
4294 break;
4295
4296 tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
4297 m_failed_table->table_name, false);
4298 if (ha_create_table_from_engine(m_thd, m_failed_table->db,
4299 m_failed_table->table_name)) {
4300 result = true;
4301 break;
4302 }
4303
4304 m_thd->get_stmt_da()->reset_condition_info(m_thd);
4305 m_thd->clear_error(); // Clear error message
4306 /*
4307 Rollback to start of the current statement to release exclusive lock
4308 on table which was discovered but preserve locks from previous
4309 statements in current transaction.
4310 */
4311 m_thd->mdl_context.rollback_to_savepoint(start_of_statement_svp());
4312 break;
4313 }
4314 5 case OT_REPAIR: {
4315
3/4
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 4 times.
5 if ((result = lock_table_names(m_thd, m_failed_table, nullptr,
4316 get_timeout(), 0)))
4317 1 break;
4318
4319 4 tdc_remove_table(m_thd, TDC_RT_REMOVE_ALL, m_failed_table->db,
4320
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 m_failed_table->table_name, false);
4321
4322
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 result = auto_repair_table(m_thd, m_failed_table);
4323 /*
4324 Rollback to start of the current statement to release exclusive lock
4325 on table which was discovered but preserve locks from previous
4326 statements in current transaction.
4327 */
4328
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 m_thd->mdl_context.rollback_to_savepoint(start_of_statement_svp());
4329 4 break;
4330 }
4331 17 case OT_FIX_ROW_TYPE: {
4332 /*
4333 Since we are going to commit changes to the data-dictionary there
4334 should not be any ongoing transaction.
4335 We already have checked that the connection holds no metadata locks
4336 earlier.
4337 Still there can be transaction started by START TRANSACTION, which
4338 we don't have right to implicitly finish (even more interesting case
4339 is START TRANSACTION WITH CONSISTENT SNAPSHOT). Hence explicit check
4340 for active transaction.
4341 */
4342
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
17 assert(!m_thd->mdl_context.has_locks());
4343
4344
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 if (m_thd->in_active_multi_stmt_transaction()) {
4345 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
4346 result = true;
4347 break;
4348 }
4349
4350
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
17 if ((result = lock_table_names(m_thd, m_failed_table, nullptr,
4351 get_timeout(), 0)))
4352 break;
4353
4354
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 result = fix_row_type(m_thd, m_failed_table);
4355
4356
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 m_thd->mdl_context.release_transactional_locks();
4357 17 break;
4358 }
4359 default:
4360 assert(0);
4361 }
4362
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
35 m_thd->pop_internal_handler();
4363 /*
4364 Reset the pointers to conflicting MDL request and the
4365 TABLE_LIST element, set when we need auto-discovery or repair,
4366 for safety.
4367 */
4368 35 m_failed_table = nullptr;
4369 /*
4370 Reset flag indicating that we have already acquired protection
4371 against GRL. It is no longer valid as the corresponding lock was
4372 released by close_tables_for_reopen().
4373 */
4374 35 m_has_protection_against_grl = false;
4375 /* Prepare for possible another back-off. */
4376 35 m_action = OT_NO_ACTION;
4377 35 return result;
4378 35 }
4379
4380 /*
4381 Return a appropriate read lock type given a table object.
4382
4383 @param thd Thread context
4384 @param prelocking_ctx Prelocking context.
4385 @param table_list Table list element for table to be locked.
4386 @param routine_modifies_data
4387 Some routine that is invoked by statement
4388 modifies data.
4389
4390 @remark Due to a statement-based replication limitation, statements such as
4391 INSERT INTO .. SELECT FROM .. and CREATE TABLE .. SELECT FROM need
4392 to grab a TL_READ_NO_INSERT lock on the source table in order to
4393 prevent the replication of a concurrent statement that modifies the
4394 source table. If such a statement gets applied on the slave before
4395 the INSERT .. SELECT statement finishes, data on the master could
4396 differ from data on the slave and end-up with a discrepancy between
4397 the binary log and table state.
4398 This also applies to SELECT/SET/DO statements which use stored
4399 functions. Calls to such functions are going to be logged as a
4400 whole and thus should be serialized against concurrent changes
4401 to tables used by those functions. This is avoided when functions
4402 do not modify data but only read it, since in this case nothing is
4403 written to the binary log. Argument routine_modifies_data
4404 denotes the same. So effectively, if the statement is not a
4405 LOCK TABLE, not a update query and routine_modifies_data is false
4406 then prelocking_placeholder does not take importance.
4407
4408 Furthermore, this does not apply to I_S and log tables as it's
4409 always unsafe to replicate such tables under statement-based
4410 replication as the table on the slave might contain other data
4411 (ie: general_log is enabled on the slave). The statement will
4412 be marked as unsafe for SBR in decide_logging_format().
4413 @remark Note that even in prelocked mode it is important to correctly
4414 determine lock type value. In this mode lock type is passed to
4415 handler::start_stmt() method and can be used by storage engine,
4416 for example, to determine what kind of row locks it should acquire
4417 when reading data from the table.
4418 */
4419
4420 4164080 thr_lock_type read_lock_type_for_table(THD *thd,
4421 Query_tables_list *prelocking_ctx,
4422 TABLE_LIST *table_list,
4423 bool routine_modifies_data) {
4424 /*
4425 In cases when this function is called for a sub-statement executed in
4426 prelocked mode we can't rely on OPTION_BIN_LOG flag in THD::options
4427 bitmap to determine that binary logging is turned on as this bit can
4428 be cleared before executing sub-statement. So instead we have to look
4429 at THD::variables::sql_log_bin member.
4430 */
4431
4/4
✓ Branch 0 taken 3720682 times.
✓ Branch 1 taken 443404 times.
✓ Branch 2 taken 3600965 times.
✓ Branch 3 taken 119717 times.
4164080 bool log_on = mysql_bin_log.is_open() && thd->variables.sql_log_bin;
4432
4433 /*
4434 When we do not write to binlog or when we use row based replication,
4435 it is safe to use a weaker lock.
4436 */
4437
4/4
✓ Branch 0 taken 3600972 times.
✓ Branch 1 taken 563114 times.
✓ Branch 2 taken 2692052 times.
✓ Branch 3 taken 908920 times.
4164086 if (log_on == false || thd->variables.binlog_format == BINLOG_FORMAT_ROW)
4438 3255166 return TL_READ;
4439
4440
2/2
✓ Branch 0 taken 908669 times.
✓ Branch 1 taken 251 times.
908920 if ((table_list->table->s->table_category == TABLE_CATEGORY_LOG) ||
4441
2/2
✓ Branch 0 taken 908277 times.
✓ Branch 1 taken 392 times.
908669 (table_list->table->s->table_category == TABLE_CATEGORY_RPL_INFO) ||
4442
2/2
✓ Branch 0 taken 908231 times.
✓ Branch 1 taken 46 times.
908277 (table_list->table->s->table_category == TABLE_CATEGORY_GTID) ||
4443
2/2
✓ Branch 0 taken 93028 times.
✓ Branch 1 taken 815203 times.
908231 (table_list->table->s->table_category == TABLE_CATEGORY_PERFORMANCE))
4444 93717 return TL_READ;
4445
4446 // SQL queries which updates data need a stronger lock.
4447
2/2
✓ Branch 0 taken 9976 times.
✓ Branch 1 taken 805224 times.
815203 if (is_update_query(prelocking_ctx->sql_command)) return TL_READ_NO_INSERT;
4448
4449 /*
4450 table_list is placeholder for prelocking.
4451 Ignore prelocking_placeholder status for non "LOCK TABLE" statement's
4452 table_list objects when routine_modifies_data is false.
4453 */
4454
4/4
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 805153 times.
✓ Branch 2 taken 40 times.
✓ Branch 3 taken 31 times.
805224 if (table_list->prelocking_placeholder &&
4455
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 39 times.
40 (routine_modifies_data || thd->in_lock_tables))
4456 32 return TL_READ_NO_INSERT;
4457
4458
2/2
✓ Branch 0 taken 5116 times.
✓ Branch 1 taken 800076 times.
805192 if (thd->locked_tables_mode > LTM_LOCK_TABLES) return TL_READ_NO_INSERT;
4459
4460 800076 return TL_READ;
4461 }
4462
4463 /**
4464 Process table's foreign keys (if any) by prelocking algorithm.
4465
4466 @param thd Thread context.
4467 @param prelocking_ctx Prelocking context of the statement.
4468 @param share Table's share.
4469 @param is_insert Indicates whether statement is going to INSERT
4470 into the table.
4471 @param is_update Indicates whether statement is going to UPDATE
4472 the table.
4473 @param is_delete Indicates whether statement is going to DELETE
4474 from the table.
4475 @param belong_to_view Uppermost view which uses this table element
4476 (nullptr - if it is not used by a view).
4477 @param[out] need_prelocking Set to true if method detects that prelocking
4478 required, not changed otherwise.
4479 */
4480 8130373 static void process_table_fks(THD *thd, Query_tables_list *prelocking_ctx,
4481 TABLE_SHARE *share, bool is_insert,
4482 bool is_update, bool is_delete,
4483 TABLE_LIST *belong_to_view,
4484 bool *need_prelocking) {
4485
4/4
✓ Branch 0 taken 6168783 times.
✓ Branch 1 taken 1961590 times.
✓ Branch 2 taken 6168070 times.
✓ Branch 3 taken 713 times.
8130373 if (!share->foreign_keys && !share->foreign_key_parents) {
4486 /*
4487 This table doesn't participate in any foreign keys, so nothing to
4488 process.
4489 */
4490 6168070 return;
4491 }
4492
4493 1962303 *need_prelocking = true;
4494
4495 /*
4496 In lower-case-table-names == 2 mode we store original versions of db
4497 and table names for tables participating in FK relationship, even
4498 though their comparison is performed in case insensitive fashion.
4499 Therefore we need to normalize/lowercase these names while prelocking
4500 set key is constructing from them.
4501 */
4502 1962303 bool normalize_db_names = (lower_case_table_names == 2);
4503 1962303 Sp_name_normalize_type name_normalize_type =
4504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1962303 times.
1962303 (lower_case_table_names == 2) ? Sp_name_normalize_type::LOWERCASE_NAME
4505 : Sp_name_normalize_type::LEAVE_AS_IS;
4506
4507
4/4
✓ Branch 0 taken 846 times.
✓ Branch 1 taken 1961457 times.
✓ Branch 2 taken 745 times.
✓ Branch 3 taken 101 times.
1962303 if (is_insert || is_update) {
4508 3924116 for (TABLE_SHARE_FOREIGN_KEY_INFO *fk = share->foreign_key;
4509
2/2
✓ Branch 0 taken 1961914 times.
✓ Branch 1 taken 1962202 times.
3924116 fk < share->foreign_key + share->foreign_keys; ++fk) {
4510 1961914 (void)sp_add_used_routine(
4511 prelocking_ctx, thd->stmt_arena,
4512 Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK,
4513 fk->referenced_table_db.str, fk->referenced_table_db.length,
4514 fk->referenced_table_name.str, fk->referenced_table_name.length,
4515 normalize_db_names, name_normalize_type, false, belong_to_view);
4516 }
4517 }
4518
4519
4/4
✓ Branch 0 taken 1961983 times.
✓ Branch 1 taken 320 times.
✓ Branch 2 taken 1957972 times.
✓ Branch 3 taken 4011 times.
1962303 if (is_update || is_delete) {
4520 3916248 for (TABLE_SHARE_FOREIGN_KEY_PARENT_INFO *fk_p = share->foreign_key_parent;
4521
2/2
✓ Branch 0 taken 1957956 times.
✓ Branch 1 taken 1958292 times.
3916248 fk_p < share->foreign_key_parent + share->foreign_key_parents;
4522 ++fk_p) {
4523
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 1957620 times.
1957956 if ((is_update &&
4524
2/2
✓ Branch 0 taken 175 times.
✓ Branch 1 taken 161 times.
336 (fk_p->update_rule == dd::Foreign_key::RULE_NO_ACTION ||
4525
4/4
✓ Branch 0 taken 170 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 1957624 times.
✓ Branch 3 taken 166 times.
1957795 fk_p->update_rule == dd::Foreign_key::RULE_RESTRICT)) ||
4526 1957624 (is_delete &&
4527
2/2
✓ Branch 0 taken 123 times.
✓ Branch 1 taken 1957501 times.
1957624 (fk_p->delete_rule == dd::Foreign_key::RULE_NO_ACTION ||
4528
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 105 times.
123 fk_p->delete_rule == dd::Foreign_key::RULE_RESTRICT))) {
4529 1957685 (void)sp_add_used_routine(
4530 prelocking_ctx, thd->stmt_arena,
4531 Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK,
4532 fk_p->referencing_table_db.str, fk_p->referencing_table_db.length,
4533 fk_p->referencing_table_name.str,
4534 fk_p->referencing_table_name.length, normalize_db_names,
4535 name_normalize_type, false, belong_to_view);
4536 }
4537
4538
2/2
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 1957620 times.
1957956 if ((is_update &&
4539
2/2
✓ Branch 0 taken 184 times.
✓ Branch 1 taken 152 times.
336 (fk_p->update_rule == dd::Foreign_key::RULE_CASCADE ||
4540
2/2
✓ Branch 0 taken 166 times.
✓ Branch 1 taken 18 times.
184 fk_p->update_rule == dd::Foreign_key::RULE_SET_NULL ||
4541
3/4
✓ Branch 0 taken 166 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1957648 times.
✓ Branch 3 taken 138 times.
1957786 fk_p->update_rule == dd::Foreign_key::RULE_SET_DEFAULT)) ||
4542 1957648 (is_delete &&
4543
2/2
✓ Branch 0 taken 1957630 times.
✓ Branch 1 taken 18 times.
1957648 (fk_p->delete_rule == dd::Foreign_key::RULE_SET_NULL ||
4544
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1957630 times.
1957630 fk_p->delete_rule == dd::Foreign_key::RULE_SET_DEFAULT))) {
4545 188 (void)sp_add_used_routine(
4546 prelocking_ctx, thd->stmt_arena,
4547 Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE,
4548 fk_p->referencing_table_db.str, fk_p->referencing_table_db.length,
4549 fk_p->referencing_table_name.str,
4550 fk_p->referencing_table_name.length, normalize_db_names,
4551 name_normalize_type, false, belong_to_view);
4552 }
4553
4554
4/4
✓ Branch 0 taken 1957652 times.
✓ Branch 1 taken 304 times.
✓ Branch 2 taken 100 times.
✓ Branch 3 taken 1957552 times.
1957956 if (is_delete && fk_p->delete_rule == dd::Foreign_key::RULE_CASCADE) {
4555 100 (void)sp_add_used_routine(
4556 prelocking_ctx, thd->stmt_arena,
4557 Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE,
4558 fk_p->referencing_table_db.str, fk_p->referencing_table_db.length,
4559 fk_p->referencing_table_name.str,
4560 fk_p->referencing_table_name.length, normalize_db_names,
4561 name_normalize_type, false, belong_to_view);
4562 }
4563 }
4564 }
4565 }
4566
4567 /**
4568 Handle element of prelocking set other than table. E.g. cache routine
4569 and, if prelocking strategy prescribes so, extend the prelocking set
4570 with tables and routines used by it.
4571
4572 @param[in] thd Thread context.
4573 @param[in] prelocking_ctx Prelocking context.
4574 @param[in] rt Element of prelocking set to be processed.
4575 @param[in] prelocking_strategy Strategy which specifies how the
4576 prelocking set should be extended when
4577 one of its elements is processed.
4578 @param[in] has_prelocking_list Indicates that prelocking set/list for
4579 this statement has already been built.
4580 @param[in] ot_ctx Context of open_table used to recover from
4581 locking failures.
4582 @param[out] need_prelocking Set to true if it was detected that this
4583 statement will require prelocked mode for
4584 its execution, not touched otherwise.
4585 @param[out] routine_modifies_data Set to true if it was detected that this
4586 routine does modify table data.
4587
4588 @retval false Success.
4589 @retval true Failure (Conflicting metadata lock, OOM, other errors).
4590 */
4591
4592 4223363 static bool open_and_process_routine(
4593 THD *thd, Query_tables_list *prelocking_ctx, Sroutine_hash_entry *rt,
4594 Prelocking_strategy *prelocking_strategy, bool has_prelocking_list,
4595 Open_table_context *ot_ctx, bool *need_prelocking,
4596 bool *routine_modifies_data) {
4597 4223363 *routine_modifies_data = false;
4598
1/2
✓ Branch 0 taken 4223367 times.
✗ Branch 1 not taken.
4223363 DBUG_TRACE;
4599
4600
3/4
✓ Branch 0 taken 277657 times.
✓ Branch 1 taken 25856 times.
✓ Branch 2 taken 3919854 times.
✗ Branch 3 not taken.
4223367 switch (rt->type()) {
4601 277657 case Sroutine_hash_entry::FUNCTION:
4602 case Sroutine_hash_entry::PROCEDURE: {
4603 sp_head *sp;
4604 /*
4605 Try to get MDL lock on the routine.
4606 Note that we do not take locks on top-level CALLs as this can
4607 lead to a deadlock. Not locking top-level CALLs does not break
4608 the binlog as only the statements in the called procedure show
4609 up there, not the CALL itself.
4610 */
4611
6/6
✓ Branch 0 taken 213422 times.
✓ Branch 1 taken 64235 times.
✓ Branch 2 taken 51708 times.
✓ Branch 3 taken 161714 times.
✓ Branch 4 taken 115943 times.
✓ Branch 5 taken 161714 times.
491079 if (rt != prelocking_ctx->sroutines_list.first ||
4612 213422 rt->type() != Sroutine_hash_entry::PROCEDURE) {
4613 115943 MDL_request mdl_request;
4614 115943 MDL_key mdl_key;
4615
4616
2/2
✓ Branch 0 taken 115585 times.
✓ Branch 1 taken 358 times.
115943 if (rt->type() == Sroutine_hash_entry::FUNCTION)
4617
4/8
✓ Branch 0 taken 115585 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 115585 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 115585 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 115585 times.
✗ Branch 7 not taken.
115585 dd::Function::create_mdl_key(rt->db(), rt->name(), &mdl_key);
4618 else
4619
4/8
✓ Branch 0 taken 358 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 358 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 358 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 358 times.
✗ Branch 7 not taken.
358 dd::Procedure::create_mdl_key(rt->db(), rt->name(), &mdl_key);
4620
4621
1/2
✓ Branch 0 taken 115943 times.
✗ Branch 1 not taken.
115943 MDL_REQUEST_INIT_BY_KEY(&mdl_request, &mdl_key, MDL_SHARED,
4622 MDL_TRANSACTION);
4623
4624 /*
4625 Waiting for a conflicting metadata lock to go away may
4626 lead to a deadlock, detected by MDL subsystem.
4627 If possible, we try to resolve such deadlocks by releasing all
4628 metadata locks and restarting the pre-locking process.
4629 To prevent the error from polluting the Diagnostics Area
4630 in case of successful resolution, install a special error
4631 handler for ER_LOCK_DEADLOCK error.
4632 */
4633 115943 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
4634
4635
1/2
✓ Branch 0 taken 115943 times.
✗ Branch 1 not taken.
115943 thd->push_internal_handler(&mdl_deadlock_handler);
4636 bool result =
4637
1/2
✓ Branch 0 taken 115943 times.
✗ Branch 1 not taken.
115943 thd->mdl_context.acquire_lock(&mdl_request, ot_ctx->get_timeout());
4638
1/2
✓ Branch 0 taken 115943 times.
✗ Branch 1 not taken.
115943 thd->pop_internal_handler();
4639
4640
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 115942 times.
115943 if (result) return true;
4641
4642
3/4
✓ Branch 0 taken 107361 times.
✓ Branch 1 taken 8581 times.
✓ Branch 2 taken 107361 times.
✗ Branch 3 not taken.
115942 DEBUG_SYNC(thd, "after_shared_lock_pname");
4643
4644 /* Ensures the routine is up-to-date and cached, if exists. */
4645
3/4
✓ Branch 0 taken 115942 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 115941 times.
115942 if (sp_cache_routine(thd, rt, has_prelocking_list, &sp)) return true;
4646
4647 /* Remember the version of the routine in the parse tree. */
4648
3/4
✓ Branch 0 taken 115941 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 119 times.
✓ Branch 3 taken 115822 times.
115941 if (check_and_update_routine_version(thd, rt, sp)) return true;
4649
4650 /* 'sp' is NULL when there is no such routine. */
4651
2/2
✓ Branch 0 taken 115722 times.
✓ Branch 1 taken 100 times.
115822 if (sp) {
4652 115722 *routine_modifies_data = sp->modifies_data();
4653
4654
2/2
✓ Branch 0 taken 115362 times.
✓ Branch 1 taken 360 times.
115722 if (!has_prelocking_list)
4655
1/2
✓ Branch 0 taken 115362 times.
✗ Branch 1 not taken.
115362 prelocking_strategy->handle_routine(thd, prelocking_ctx, rt, sp,
4656 need_prelocking);
4657 }
4658
2/2
✓ Branch 0 taken 115822 times.
✓ Branch 1 taken 121 times.
115943 } else {
4659 /*
4660 If it's a top level call, just make sure we have a recent
4661 version of the routine, if it exists.
4662 Validating routine version is unnecessary, since CALL
4663 does not affect the prepared statement prelocked list.
4664 */
4665
3/4
✓ Branch 0 taken 161712 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 161710 times.
161714 if (sp_cache_routine(thd, rt, false, &sp)) return true;
4666 }
4667 277532 } break;
4668 25856 case Sroutine_hash_entry::TRIGGER:
4669 /**
4670 We add trigger entries to lex->sroutines_list, but we don't
4671 load them here. The trigger entry is only used when building
4672 a transitive closure of objects used in a statement, to avoid
4673 adding to this closure objects that are used in the trigger more
4674 than once.
4675 E.g. if a trigger trg refers to table t2, and the trigger table t1
4676 is used multiple times in the statement (say, because it's used in
4677 function f1() twice), we will only add t2 once to the list of
4678 tables to prelock.
4679
4680 We don't take metadata locks on triggers either: they are protected
4681 by a respective lock on the table, on which the trigger is defined.
4682
4683 The only two cases which give "trouble" are SHOW CREATE TRIGGER
4684 and DROP TRIGGER statements. For these, statement syntax doesn't
4685 specify the table on which this trigger is defined, so we have
4686 to make a "dirty" read in the data dictionary to find out the
4687 table name. Once we discover the table name, we take a metadata
4688 lock on it, and this protects all trigger operations.
4689 Of course the table, in theory, may disappear between the dirty
4690 read and metadata lock acquisition, but in that case we just return
4691 a run-time error.
4692
4693 Grammar of other trigger DDL statements (CREATE, DROP) requires
4694 the table to be specified explicitly, so we use the table metadata
4695 lock to protect trigger metadata in these statements. Similarly, in
4696 DML we always use triggers together with their tables, and thus don't
4697 need to take separate metadata locks on them.
4698 */
4699 25856 break;
4700 3919854 case Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK:
4701 case Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK:
4702 case Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE:
4703 case Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE: {
4704
2/2
✓ Branch 0 taken 3919841 times.
✓ Branch 1 taken 13 times.
3919854 if (thd->locked_tables_mode == LTM_NONE) {
4705 3919841 MDL_request mdl_request;
4706
4707 /*
4708 Adjust metadata lock type according to the table's role in the
4709 FK relationship. Also acquire stronger locks when we are locking
4710 on behalf of LOCK TABLES.
4711 */
4712 enum_mdl_type mdl_lock_type;
4713 3919841 bool executing_LT = (prelocking_ctx->sql_command == SQLCOM_LOCK_TABLES);
4714
4715
6/6
✓ Branch 0 taken 1957964 times.
✓ Branch 1 taken 1961877 times.
✓ Branch 2 taken 1957681 times.
✓ Branch 3 taken 283 times.
✓ Branch 4 taken 3919558 times.
✓ Branch 5 taken 283 times.
5877805 if (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK ||
4716 1957964 rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK) {
4717 3919558 mdl_lock_type =
4718
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 3919505 times.
3919558 (executing_LT ? MDL_SHARED_READ_ONLY : MDL_SHARED_READ);
4719 } else {
4720 283 mdl_lock_type =
4721
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 262 times.
283 (executing_LT ? MDL_SHARED_NO_READ_WRITE : MDL_SHARED_WRITE);
4722 }
4723
4724
1/2
✓ Branch 0 taken 3919841 times.
✗ Branch 1 not taken.
3919841 MDL_REQUEST_INIT_BY_PART_KEY(&mdl_request, MDL_key::TABLE,
4725 rt->part_mdl_key(),
4726 rt->part_mdl_key_length(), rt->db_length(),
4727 mdl_lock_type, MDL_TRANSACTION);
4728
4729 3919841 MDL_deadlock_handler mdl_deadlock_handler(ot_ctx);
4730
4731
1/2
✓ Branch 0 taken 3919841 times.
✗ Branch 1 not taken.
3919841 thd->push_internal_handler(&mdl_deadlock_handler);
4732 bool result =
4733
1/2
✓ Branch 0 taken 3919841 times.
✗ Branch 1 not taken.
3919841 thd->mdl_context.acquire_lock(&mdl_request, ot_ctx->get_timeout());
4734
1/2
✓ Branch 0 taken 3919841 times.
✗ Branch 1 not taken.
3919841 thd->pop_internal_handler();
4735
4736
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3919841 times.
3919841 if (result) return true;
4737
1/2
✓ Branch 0 taken 3919841 times.
✗ Branch 1 not taken.
3919841 } else {
4738 /*
4739 This function is called only if we are not in prelocked mode
4740 already. So we must be handling statement executed under
4741 LOCK TABLES in this case.
4742 */
4743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 assert(thd->locked_tables_mode == LTM_LOCK_TABLES);
4744
4745 /*
4746 Even though LOCK TABLES tries to automatically lock parent and child
4747 tables which might be necessary for foreign key checks/actions, there
4748 are some cases when we might miss them. So it is better to check that
4749 we have appropriate metadata lock explicitly and error out if not.
4750
4751 Some examples of problematic cases are:
4752
4753 *) We are executing DELETE FROM t1 under LOCK TABLES t1 READ
4754 and table t1 is a parent in a foreign key.
4755 In this case error about inappropriate lock on t1 will be
4756 reported at later stage than prelocking set is built.
4757 So we can't assume/assert that we have proper lock on the
4758 corresponding child table here.
4759
4760 *) Table t1 has a trigger, which contains DELETE FROM t2 and
4761 t2 is participating in FK as parent. In such situation
4762 LOCK TABLE t1 WRITE will lock t2 for write implicitly
4763 so both updates and delete on t2 will be allowed. However,
4764 t3 will be locked only in a way as if only deletes from
4765 t2 were allowed.
4766
4767 *) Prelocking list has been built earlier. Both child and parent
4768 definitions might have changed since this time so at LOCK TABLES
4769 time FK which corresponds to this element of prelocked set
4770 might be no longer around. In theory, we might be processing
4771 statement which is not marked as requiring prelocked set invalidation
4772 (and thus ignoring table version mismatches) or tables might be missing
4773 and this error can be suppressed. In such case we might not have
4774 appropriate metadata lock on our child/parent table.
4775 */
4776
6/6
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 3 times.
20 if (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_PARENT_CHECK ||
4777 7 rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_CHECK) {
4778
4/6
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 9 times.
10 if (!thd->mdl_context.owns_equal_or_stronger_lock(
4779 MDL_key::TABLE, rt->db(), rt->name(), MDL_SHARED_READ_ONLY)) {
4780
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 my_error(ER_TABLE_NOT_LOCKED, MYF(0), rt->name());
4781 1 return true;
4782 }
4783 } else {
4784
4/6
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2 times.
3 if (!thd->mdl_context.owns_equal_or_stronger_lock(
4785 MDL_key::TABLE, rt->db(), rt->name(),
4786 MDL_SHARED_NO_READ_WRITE)) {
4787
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), rt->name());
4788 1 return true;
4789 }
4790 }
4791 }
4792
4793
6/6
✓ Branch 0 taken 3919664 times.
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 97 times.
✓ Branch 3 taken 3919567 times.
✓ Branch 4 taken 285 times.
✓ Branch 5 taken 3919567 times.
7839516 if (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE ||
4794 3919664 rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE) {
4795 /*
4796 In order to continue building prelocked set or validating
4797 prelocked set which already has been built we need to get
4798 access to table's TABLE_SHARE.
4799
4800 Getting unused TABLE object is more scalable that going
4801 directly for the TABLE_SHARE. If there are no unused TABLE
4802 object we might get at least pointer to the TABLE_SHARE
4803 from the table cache.
4804
4805 Note that under LOCK TABLES we can't rely on that table is
4806 going to be in THD::open_tables list, as LOCK TABLES only
4807 pre-acquires metadata locks on FK tables but doesn't
4808 pre-open them.
4809
4810 TODO: Perhaps we should give it a try as it can be more
4811 scalability friendly.
4812 */
4813 285 Table_cache *tc = table_cache_manager.get_cache(thd);
4814 TABLE *table;
4815 TABLE_SHARE *share;
4816
4817
1/2
✓ Branch 0 taken 285 times.
✗ Branch 1 not taken.
285 tc->lock();
4818
4819
1/2
✓ Branch 0 taken 285 times.
✗ Branch 1 not taken.
285 table = tc->get_table(thd, rt->part_mdl_key(),
4820 rt->part_mdl_key_length(), &share);
4821
4822
2/2
✓ Branch 0 taken 189 times.
✓ Branch 1 taken 96 times.
285 if (table) {
4823
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 189 times.
189 assert(table->s == share);
4824 /*
4825 Don't check if TABLE_SHARE::version matches version of tables
4826 previously opened by this statement. It might be problematic
4827 under LOCK TABLES and possible version difference can't affect
4828 FK-related part of prelocking set.
4829 */
4830
1/2
✓ Branch 0 taken 189 times.
✗ Branch 1 not taken.
189 tc->unlock();
4831
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 75 times.
96 } else if (share) {
4832 /*
4833 TODO: If we constantly hit this case it would harm scalability...
4834 Perhaps we need to create new unused TABLE instance in this
4835 case.
4836 */
4837
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 mysql_mutex_lock(&LOCK_open);
4838
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 tc->unlock();
4839
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 share->increment_ref_count();
4840
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 mysql_mutex_unlock(&LOCK_open);
4841
4842 /*
4843 Again, when building part of prelocking set related to foreign keys
4844 we can ignore fact that TABLE_SHARE::version is old.
4845 */
4846 } else {
4847
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 tc->unlock();
4848
4849 /*
4850 If we are validating existing prelocking set then the table
4851 might have been dropped. We suppress this error in this case.
4852 Prelocking set will be either invalidated, or error will be
4853 reported the parent table is accessed.
4854
4855 TODO: Perhaps we need to use get_table_share_with_discover()
4856 here but it gets complicated under LOCK TABLES.
4857 */
4858 75 No_such_table_error_handler no_such_table_handler;
4859
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 thd->push_internal_handler(&no_such_table_handler);
4860
4861
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 mysql_mutex_lock(&LOCK_open);
4862
2/4
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 75 times.
✗ Branch 3 not taken.
75 share = get_table_share(thd, rt->db(), rt->name(), rt->part_mdl_key(),
4863 rt->part_mdl_key_length(), true);
4864
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 mysql_mutex_unlock(&LOCK_open);
4865
4866
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 thd->pop_internal_handler();
4867
4868
5/6
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 74 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 74 times.
75 if (!share && no_such_table_handler.safely_trapped_errors()) {
4869 1 break; // Jump out switch without error.
4870 }
4871
4872
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 74 times.
74 if (!share) {
4873 return true;
4874 }
4875
4876
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 73 times.
74 if (share->is_view) {
4877 /*
4878 Eeek! Somebody replaced the child table with a view. This can
4879 happen only when we are validating existing prelocked set.
4880 Parent either have been dropped or its definition has been
4881 changed. In either case our child table won't be accessed
4882 through the foreign key.
4883 */
4884
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(has_prelocking_list);
4885
4886
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_lock(&LOCK_open);
4887
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 release_table_share(share);
4888
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 mysql_mutex_unlock(&LOCK_open);
4889
4890
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 if (ask_to_reprepare(thd)) return true;
4891
4892 break; // Jump out switch without error.
4893 }
4894
3/3
✓ Branch 0 taken 73 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
75 }
4895
4896 189 auto release_table_lambda = [thd](TABLE *tab) {
4897 189 release_or_close_table(thd, tab);
4898 472 };
4899 std::unique_ptr<TABLE, decltype(release_table_lambda)>
4900 283 release_table_guard(table, release_table_lambda);
4901
4902 /*
4903 We need to explicitly release TABLE_SHARE only if we don't
4904 have TABLE object.
4905 */
4906 94 auto release_share_lambda = [](TABLE_SHARE *tsh) {
4907 94 mysql_mutex_lock(&LOCK_open);
4908 94 release_table_share(tsh);
4909 94 mysql_mutex_unlock(&LOCK_open);
4910 94 };
4911 std::unique_ptr<TABLE_SHARE, decltype(release_share_lambda)>
4912 release_share_guard((table ? nullptr : share),
4913
2/2
✓ Branch 0 taken 94 times.
✓ Branch 1 taken 189 times.
283 release_share_lambda);
4914
4915 /*
4916 We need to maintain versioning of the prelocked tables since this
4917 is needed for correct handling of prepared statements to catch
4918 situations where a prelocked table (which is added to the prelocked
4919 set during PREPARE) is changed between repeated executions of the
4920 prepared statement.
4921 */
4922
1/2
✓ Branch 0 taken 283 times.
✗ Branch 1 not taken.
283 int64 share_version = share->get_table_ref_version();
4923
4924
2/2
✓ Branch 0 taken 276 times.
✓ Branch 1 taken 7 times.
283 if (rt->m_cache_version != share_version) {
4925 /*
4926 Version of the cached table share is different from the
4927 previous execution of the prepared statement, and it is
4928 unacceptable for this SQLCOM.
4929 */
4930
3/4
✓ Branch 0 taken 276 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 275 times.
276 if (ask_to_reprepare(thd)) return true;
4931 /* Always maintain the latest cache version. */
4932 275 rt->m_cache_version = share_version;
4933 }
4934
4935 /*
4936 If the child may be affected by update/delete and is in a read only
4937 schema, we must reject the statement.
4938 */
4939
3/4
✓ Branch 0 taken 282 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 274 times.
282 if (check_schema_readonly(thd, rt->db())) {
4940
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 my_error(ER_SCHEMA_READ_ONLY, MYF(0), rt->db());
4941 8 return true;
4942 }
4943
4944
2/2
✓ Branch 0 taken 267 times.
✓ Branch 1 taken 7 times.
274 if (!has_prelocking_list) {
4945 bool is_update =
4946 267 (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_UPDATE);
4947 bool is_delete =
4948 267 (rt->type() == Sroutine_hash_entry::FK_TABLE_ROLE_CHILD_DELETE);
4949
4950
1/2
✓ Branch 0 taken 267 times.
✗ Branch 1 not taken.
267 process_table_fks(thd, prelocking_ctx, share, false, is_update,
4951 is_delete, rt->belong_to_view, need_prelocking);
4952 }
4953
4/4
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 9 times.
✓ Branch 2 taken 274 times.
✓ Branch 3 taken 9 times.
292 }
4954 3919841 } break;
4955 default:
4956 /* Impossible type value. */
4957 assert(0);
4958 }
4959 4223230 return false;
4960 4223365 }
4961
4962 /**
4963 Handle table list element by obtaining metadata lock, opening table or view
4964 and, if prelocking strategy prescribes so, extending the prelocking set with
4965 tables and routines used by it.
4966
4967 @param[in] thd Thread context.
4968 @param[in] lex LEX structure for statement.
4969 @param[in] tables Table list element to be processed.
4970 @param[in,out] counter Number of tables which are open.
4971 @param[in] prelocking_strategy Strategy which specifies how the
4972 prelocking set should be extended
4973 when table or view is processed.
4974 @param[in] has_prelocking_list Indicates that prelocking set/list for
4975 this statement has already been built.
4976 @param[in] ot_ctx Context used to recover from a failed
4977 open_table() attempt.
4978
4979 @retval false Success.
4980 @retval true Error, reported unless there is a chance to recover from it.
4981 */
4982
4983 108491514 static bool open_and_process_table(THD *thd, LEX *lex, TABLE_LIST *const tables,
4984 uint *counter,
4985 Prelocking_strategy *prelocking_strategy,
4986 bool has_prelocking_list,
4987 Open_table_context *ot_ctx) {
4988 108491514 bool error = false;
4989 108491514 bool safe_to_ignore_table = false;
4990
1/2
✓ Branch 0 taken 108493662 times.
✗ Branch 1 not taken.
108491514 DBUG_TRACE;
4991
3/4
✓ Branch 0 taken 99529724 times.
✓ Branch 1 taken 8963653 times.
✓ Branch 2 taken 99530078 times.
✗ Branch 3 not taken.
108493662 DEBUG_SYNC(thd, "open_and_process_table");
4992
4993 /*
4994 Ignore placeholders for unnamed derived tables, as they are fully resolved
4995 by the optimizer.
4996 */
4997
8/8
✓ Branch 0 taken 108250363 times.
✓ Branch 1 taken 243380 times.
✓ Branch 2 taken 108242674 times.
✓ Branch 3 taken 7655 times.
✓ Branch 4 taken 28 times.
✓ Branch 5 taken 108242629 times.
✓ Branch 6 taken 251063 times.
✓ Branch 7 taken 108242629 times.
216736388 if (tables->is_derived() || tables->is_table_function() ||
4998 108242674 tables->is_recursive_reference())
4999 251063 goto end;
5000
5001
2/2
✓ Branch 0 taken 196 times.
✓ Branch 1 taken 108241615 times.
108242629 assert(!tables->common_table_expr());
5002
5003 /*
5004 If this TABLE_LIST object is a placeholder for an information_schema
5005 table, create a temporary table to represent the information_schema
5006 table in the query. Do not fill it yet - will be filled during
5007 execution.
5008 */
5009
2/2
✓ Branch 0 taken 219548 times.
✓ Branch 1 taken 108022067 times.
108241615 if (tables->schema_table) {
5010 /*
5011 Since we no longer set TABLE_LIST::schema_table/table for table
5012 list elements representing mergeable view, we can't meet a table
5013 list element which represent information_schema table and a view
5014 at the same time. Otherwise, acquiring metadata lock om the view
5015 would have been necessary.
5016 */
5017
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 219548 times.
219548 assert(!tables->is_view());
5018
5019
3/6
✓ Branch 0 taken 219548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 219548 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 219548 times.
✗ Branch 5 not taken.
439096 if (!mysql_schema_table(thd, lex, tables) &&
5020
2/4
✓ Branch 0 taken 219548 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 219548 times.
✗ Branch 3 not taken.
219548 !check_and_update_table_version(thd, tables, tables->table->s)) {
5021 219548 goto end;
5022 }
5023 error = true;
5024 goto end;
5025 }
5026
5/8
✓ Branch 0 taken 108022544 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 108022685 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6426 times.
✓ Branch 5 taken 108016259 times.
✓ Branch 6 taken 5625 times.
✗ Branch 7 not taken.
108022067 DBUG_PRINT("tcache", ("opening table: '%s'.'%s' item: %p", tables->db,
5027 tables->table_name, tables));
5028
5029 108021884 (*counter)++;
5030
5031 /*
5032 Not a placeholder so this must be a base/temporary table or view.
5033 Open it:
5034 */
5035
5036 /*
5037 A TABLE_LIST object may have an associated open TABLE object
5038 (TABLE_LIST::table is not NULL) if it represents a pre-opened temporary
5039 table, or is a materialized view. (Derived tables are not handled here).
5040 */
5041
5042
6/8
✓ Branch 0 taken 243522 times.
✓ Branch 1 taken 107778362 times.
✓ Branch 2 taken 158 times.
✓ Branch 3 taken 243360 times.
✓ Branch 4 taken 158 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 158 times.
✗ Branch 7 not taken.
108021884 assert(tables->table == nullptr || is_temporary_table(tables) ||
5043 (tables->is_view() && tables->uses_materialization()));
5044
5045 /*
5046 OT_TEMPORARY_ONLY means that we are in CREATE TEMPORARY TABLE statement.
5047 Also such table list element can't correspond to prelocking placeholder
5048 or to underlying table of merge table.
5049 So existing temporary table should have been preopened by this moment
5050 and we can simply continue without trying to open temporary or base table.
5051 */
5052
6/8
✓ Branch 0 taken 47746 times.
✓ Branch 1 taken 107974134 times.
✓ Branch 2 taken 47745 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 47745 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47745 times.
✗ Branch 7 not taken.
108021880 assert(tables->open_type != OT_TEMPORARY_ONLY ||
5053 (tables->open_strategy && !tables->prelocking_placeholder &&
5054 tables->parent_l == nullptr));
5055
5056
6/6
✓ Branch 0 taken 107974135 times.
✓ Branch 1 taken 47744 times.
✓ Branch 2 taken 243252 times.
✓ Branch 3 taken 107731646 times.
✓ Branch 4 taken 107731688 times.
✓ Branch 5 taken 290954 times.
108021879 if (tables->open_type == OT_TEMPORARY_ONLY || is_temporary_table(tables)) {
5057 // Already "open", no action required
5058
2/2
✓ Branch 0 taken 43768 times.
✓ Branch 1 taken 107687920 times.
107731688 } else if (tables->prelocking_placeholder) {
5059 /*
5060 For the tables added by the pre-locking code, attempt to open
5061 the table but fail silently if the table does not exist.
5062 The real failure will occur when/if a statement attempts to use
5063 that table.
5064 */
5065 43768 No_such_table_error_handler no_such_table_handler;
5066
1/2
✓ Branch 0 taken 43768 times.
✗ Branch 1 not taken.
43768 thd->push_internal_handler(&no_such_table_handler);
5067
5068 /*
5069 We're opening a table from the prelocking list.
5070
5071 Since this table list element might have been added after pre-opening
5072 of temporary tables we have to try to open temporary table for it.
5073
5074 We can't simply skip this table list element and postpone opening of
5075 temporary tabletill the execution of substatement for several reasons:
5076 - Temporary table can be a MERGE table with base underlying tables,
5077 so its underlying tables has to be properly open and locked at
5078 prelocking stage.
5079 - Temporary table can be a MERGE table and we might be in PREPARE
5080 phase for a prepared statement. In this case it is important to call
5081 HA_ATTACH_CHILDREN for all merge children.
5082 This is necessary because merge children remember "TABLE_SHARE ref type"
5083 and "TABLE_SHARE def version" in the HA_ATTACH_CHILDREN operation.
5084 If HA_ATTACH_CHILDREN is not called, these attributes are not set.
5085 Then, during the first EXECUTE, those attributes need to be updated.
5086 That would cause statement re-preparing (because changing those
5087 attributes during EXECUTE is caught by THD::m_reprepare_observers).
5088 The problem is that since those attributes are not set in merge
5089 children, another round of PREPARE will not help.
5090 */
5091
1/2
✓ Branch 0 taken 43768 times.
✗ Branch 1 not taken.
43768 error = open_temporary_table(thd, tables);
5092
5093
4/6
✓ Branch 0 taken 43768 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 43265 times.
✓ Branch 3 taken 503 times.
✓ Branch 4 taken 43265 times.
✗ Branch 5 not taken.
43768 if (!error && !tables->table) error = open_table(thd, tables, ot_ctx);
5094
5095
1/2
✓ Branch 0 taken 43768 times.
✗ Branch 1 not taken.
43768 thd->pop_internal_handler();
5096 43768 safe_to_ignore_table = no_such_table_handler.safely_trapped_errors();
5097
4/4
✓ Branch 0 taken 8005 times.
✓ Branch 1 taken 107679915 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8003 times.
107731688 } else if (tables->parent_l && (thd->open_options & HA_OPEN_FOR_REPAIR)) {
5098 /*
5099 Also fail silently for underlying tables of a MERGE table if this
5100 table is opened for CHECK/REPAIR TABLE statement. This is needed
5101 to provide complete list of problematic underlying tables in
5102 CHECK/REPAIR TABLE output.
5103 */
5104 2 Repair_mrg_table_error_handler repair_mrg_table_handler;
5105
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 thd->push_internal_handler(&repair_mrg_table_handler);
5106
5107
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 error = open_temporary_table(thd, tables);
5108
3/6
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
2 if (!error && !tables->table) error = open_table(thd, tables, ot_ctx);
5109
5110
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 thd->pop_internal_handler();
5111 2 safe_to_ignore_table = repair_mrg_table_handler.safely_trapped_errors();
5112 2 } else {
5113
2/2
✓ Branch 0 taken 8003 times.
✓ Branch 1 taken 107679915 times.
107687918 if (tables->parent_l) {
5114 /*
5115 Even if we are opening table not from the prelocking list we
5116 still might need to look for a temporary table if this table
5117 list element corresponds to underlying table of a merge table.
5118 */
5119
1/2
✓ Branch 0 taken 8003 times.
✗ Branch 1 not taken.
8003 error = open_temporary_table(thd, tables);
5120 }
5121
5122
7/8
✓ Branch 0 taken 107686452 times.
✓ Branch 1 taken 1466 times.
✓ Branch 2 taken 107618644 times.
✓ Branch 3 taken 68177 times.
✓ Branch 4 taken 107619206 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 107687437 times.
✓ Branch 7 taken 850 times.
107687918 if (!error && (tables->is_view() || tables->table == nullptr))
5123
1/2
✓ Branch 0 taken 107688117 times.
✗ Branch 1 not taken.
107687437 error = open_table(thd, tables, ot_ctx);
5124 }
5125
5126
2/2
✓ Branch 0 taken 26249 times.
✓ Branch 1 taken 107996580 times.
108022829 if (error) {
5127
6/6
✓ Branch 0 taken 26214 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 382 times.
✓ Branch 3 taken 25832 times.
✓ Branch 4 taken 382 times.
✓ Branch 5 taken 25867 times.
26249 if (!ot_ctx->can_recover_from_failed_open() && safe_to_ignore_table) {
5128
3/8
✓ Branch 0 taken 382 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 382 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 382 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
382 DBUG_PRINT("info", ("open_table: ignoring table '%s'.'%s'", tables->db,
5129 tables->alias));
5130 382 error = false;
5131 }
5132 26249 goto end;
5133 }
5134
5135 // Do specific processing for a view, and skip actions that apply to tables
5136
5137
2/2
✓ Branch 0 taken 576037 times.
✓ Branch 1 taken 107420473 times.
107996580 if (tables->is_view()) {
5138 // Views do not count as tables
5139 576037 (*counter)--;
5140
5141 /*
5142 tables->next_global list consists of two parts:
5143 1) Query tables and underlying tables of views.
5144 2) Tables used by all stored routines that this statement invokes on
5145 execution.
5146 We need to know where the bound between these two parts is. If we've
5147 just opened a view, which was the last table in part #1, and it
5148 has added its base tables after itself, adjust the boundary pointer
5149 accordingly.
5150 */
5151
4/4
✓ Branch 0 taken 11670 times.
✓ Branch 1 taken 564367 times.
✓ Branch 2 taken 11646 times.
✓ Branch 3 taken 564391 times.
587707 if (lex->query_tables_own_last == &(tables->next_global) &&
5152
2/2
✓ Branch 0 taken 11646 times.
✓ Branch 1 taken 24 times.
11670 tables->view_query()->query_tables)
5153 11646 lex->query_tables_own_last = tables->view_query()->query_tables_last;
5154 /*
5155 Let us free memory used by 'sroutines' hash here since we never
5156 call destructor for this LEX.
5157 */
5158 576037 tables->view_query()->sroutines.reset();
5159 576038 goto process_view_routines;
5160 }
5161
5162 /*
5163 Special types of open can succeed but still don't set
5164 TABLE_LIST::table to anything.
5165 */
5166
4/4
✓ Branch 0 taken 2053200 times.
✓ Branch 1 taken 105367273 times.
✓ Branch 2 taken 673404 times.
✓ Branch 3 taken 1379796 times.
107420473 if (tables->open_strategy && !tables->table) goto end;
5167
5168 /*
5169 If we are not already in prelocked mode and extended table list is not
5170 yet built we might have to build the prelocking set for this statement.
5171
5172 Since currently no prelocking strategy prescribes doing anything for
5173 tables which are only read, we do below checks only if table is going
5174 to be changed.
5175 */
5176
6/6
✓ Branch 0 taken 106693687 times.
✓ Branch 1 taken 53382 times.
✓ Branch 2 taken 106686843 times.
✓ Branch 3 taken 6844 times.
✓ Branch 4 taken 26636235 times.
✓ Branch 5 taken 80110472 times.
213433550 if (thd->locked_tables_mode <= LTM_LOCK_TABLES && !has_prelocking_list &&
5177
2/2
✓ Branch 0 taken 26635949 times.
✓ Branch 1 taken 80050532 times.
106686843 tables->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE) {
5178 26636235 bool need_prelocking = false;
5179 26636235 TABLE_LIST **save_query_tables_last = lex->query_tables_last;
5180 /*
5181 Extend statement's table list and the prelocking set with
5182 tables and routines according to the current prelocking
5183 strategy.
5184
5185 For example, for DML statements we need to add tables and routines
5186 used by triggers which are going to be invoked for this element of
5187 table list and also add tables required for handling of foreign keys.
5188 */
5189 error =
5190
2/4
✓ Branch 0 taken 26636286 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26635942 times.
✗ Branch 3 not taken.
26636235 prelocking_strategy->handle_table(thd, lex, tables, &need_prelocking);
5191
5192
6/6
✓ Branch 0 taken 2008061 times.
✓ Branch 1 taken 24627881 times.
✓ Branch 2 taken 2004963 times.
✓ Branch 3 taken 3098 times.
✓ Branch 4 taken 2004963 times.
✓ Branch 5 taken 24630979 times.
26635942 if (need_prelocking && !lex->requires_prelocking())
5193 2004963 lex->mark_as_requiring_prelocking(save_query_tables_last);
5194
5195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26635918 times.
26635918 if (error) goto end;
5196 }
5197
5198 /* Check and update metadata version of a base table. */
5199
1/2
✓ Branch 0 taken 106747271 times.
✗ Branch 1 not taken.
106746390 error = check_and_update_table_version(thd, tables, tables->table->s);
5200
2/2
✓ Branch 0 taken 37673 times.
✓ Branch 1 taken 106709598 times.
106747271 if (error) goto end;
5201 /*
5202 After opening a MERGE table add the children to the query list of
5203 tables, so that they are opened too.
5204 Note that placeholders don't have the handler open.
5205 */
5206 /* MERGE tables need to access parent and child TABLE_LISTs. */
5207
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 106709598 times.
106709598 assert(tables->table->pos_in_table_list == tables);
5208 /* Non-MERGE tables ignore this call. */
5209
3/4
✓ Branch 0 taken 106548626 times.
✓ Branch 1 taken 160972 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 106710025 times.
213258651 if (tables->table->db_stat &&
5210
2/4
✓ Branch 0 taken 106549053 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 106549053 times.
106548626 tables->table->file->ha_extra(HA_EXTRA_ADD_CHILDREN_LIST)) {
5211 error = true;
5212 goto end;
5213 }
5214
5215 106710025 process_view_routines:
5216
6/8
✓ Branch 0 taken 576037 times.
✓ Branch 1 taken 106709850 times.
✓ Branch 2 taken 575881 times.
✓ Branch 3 taken 156 times.
✓ Branch 4 taken 575881 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 106709885 times.
107286063 assert((tables->is_view() &&
5217 (tables->uses_materialization() || tables->table == nullptr)) ||
5218 (!tables->is_view()));
5219
5220 /*
5221 Again we may need cache all routines used by this view and add
5222 tables used by them to table list.
5223 */
5224
6/6
✓ Branch 0 taken 576037 times.
✓ Branch 1 taken 106709849 times.
✓ Branch 2 taken 575894 times.
✓ Branch 3 taken 143 times.
✓ Branch 4 taken 106710041 times.
✓ Branch 5 taken 575845 times.
107861816 if (tables->is_view() && thd->locked_tables_mode <= LTM_LOCK_TABLES &&
5225
2/2
✓ Branch 0 taken 575846 times.
✓ Branch 1 taken 48 times.
575894 !has_prelocking_list) {
5226 575845 bool need_prelocking = false;
5227 575845 TABLE_LIST **save_query_tables_last = lex->query_tables_last;
5228
5229 error =
5230
2/4
✓ Branch 0 taken 575845 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 575846 times.
✗ Branch 3 not taken.
575845 prelocking_strategy->handle_view(thd, lex, tables, &need_prelocking);
5231
5232
6/6
✓ Branch 0 taken 33811 times.
✓ Branch 1 taken 542035 times.
✓ Branch 2 taken 33018 times.
✓ Branch 3 taken 793 times.
✓ Branch 4 taken 33018 times.
✓ Branch 5 taken 542828 times.
575846 if (need_prelocking && !lex->requires_prelocking())
5233 33018 lex->mark_as_requiring_prelocking(save_query_tables_last);
5234
5235
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 575846 times.
575846 if (error) goto end;
5236 }
5237
5238 106710041 end:
5239 108493897 return error;
5240 108493824 }
5241
5242 namespace {
5243
5244 struct schema_hash {
5245 1132600 size_t operator()(const TABLE_LIST *table) const {
5246
1/2
✓ Branch 0 taken 1132600 times.
✗ Branch 1 not taken.
1132600 return std::hash<std::string>()(std::string(table->db, table->db_length));
5247 }
5248 };
5249
5250 struct schema_key_equal {
5251 70499 bool operator()(const TABLE_LIST *a, const TABLE_LIST *b) const {
5252
1/2
✓ Branch 0 taken 70499 times.
✗ Branch 1 not taken.
140998 return a->db_length == b->db_length &&
5253
1/2
✓ Branch 0 taken 70499 times.
✗ Branch 1 not taken.
140998 memcmp(a->db, b->db, a->db_length) == 0;
5254 }
5255 };
5256
5257 } // namespace
5258
5259 /**
5260 Run the server hook called "before_dml". This is a hook originated from
5261 replication that allow server plugins to execute code before any DML
5262 instruction is executed.
5263 In case of negative outcome, it will set my_error to
5264 ER_BEFORE_DML_VALIDATION_ERROR
5265
5266 @param thd Thread context
5267
5268 @return hook outcome
5269 @retval 0 Everything is fine
5270 @retval !=0 Error in the outcome of the hook.
5271 */
5272 8269354 int run_before_dml_hook(THD *thd) {
5273 8269354 int out_value = 0;
5274
5275
1/2
✓ Branch 0 taken 8269499 times.
✗ Branch 1 not taken.
8269354 TX_TRACKER_GET(tst);
5276
1/2
✓ Branch 0 taken 8269728 times.
✗ Branch 1 not taken.
8269499 tst->add_trx_state(thd, TX_STMT_DML);
5277
5278
4/6
✓ Branch 0 taken 8269574 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 180856 times.
✓ Branch 3 taken 8088718 times.
✓ Branch 4 taken 181082 times.
✗ Branch 5 not taken.
8269728 (void)RUN_HOOK(transaction, before_dml, (thd, out_value));
5279
5280
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 8269730 times.
8269800 if (out_value) {
5281
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 tst->clear_trx_state(thd, TX_STMT_DML);
5282
1/2
✓ Branch 0 taken 44 times.
✗ Branch 1 not taken.
70 my_error(ER_BEFORE_DML_VALIDATION_ERROR, MYF(0));
5283 }
5284
5285 8269774 return out_value;
5286 }
5287
5288 /**
5289 Check whether a table being opened is a temporary table.
5290
5291 @param table table being opened
5292
5293 @return true if a table is temporary table, else false
5294 */
5295
5296 107000221 static inline bool is_temporary_table_being_opened(const TABLE_LIST *table) {
5297
2/2
✓ Branch 0 taken 106905785 times.
✓ Branch 1 taken 94436 times.
213906868 return table->open_type == OT_TEMPORARY_ONLY ||
5298
4/4
✓ Branch 0 taken 104455865 times.
✓ Branch 1 taken 2449920 times.
✓ Branch 2 taken 326251 times.
✓ Branch 3 taken 104130476 times.
211362512 (table->open_type == OT_TEMPORARY_OR_BASE &&
5299 211456948 is_temporary_table(table));
5300 }
5301
5302 /**
5303 Acquire IX metadata locks on tablespace names used by LOCK
5304 TABLES or by a DDL statement.
5305
5306 @note That the tablespace MDL locks are taken only after locks
5307 on tables are acquired. So it is recommended to maintain this
5308 same lock order across the server. It is very easy to break the
5309 this lock order if we invoke acquire_locks() with list of MDL
5310 requests which contain both MDL_key::TABLE and
5311 MDL_key::TABLESPACE. We would end-up in deadlock then.
5312
5313 @param thd Thread context.
5314 @param tables_start Start of list of tables on which locks
5315 should be acquired.
5316 @param tables_end End of list of tables.
5317 @param lock_wait_timeout Seconds to wait before timeout.
5318 @param flags Bitmap of flags to modify how the
5319 tables will be open, see open_table()
5320 description for details.
5321
5322 @retval true Failure (e.g. connection was killed)
5323 @retval false Success.
5324 */
5325 49804021 bool get_and_lock_tablespace_names(THD *thd, TABLE_LIST *tables_start,
5326 TABLE_LIST *tables_end,
5327 ulong lock_wait_timeout, uint flags) {
5328 // If this is a DISCARD or IMPORT TABLESPACE command (indicated by
5329 // the THD:: tablespace_op flag), we skip this phase, because these
5330 // commands are only used for file-per-table tablespaces, which we
5331 // do not lock. We also skip this phase if we are within the
5332 // context of a FLUSH TABLE WITH READ LOCK or FLUSH TABLE FOR EXPORT
5333 // statement, indicated by the MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK flag.
5334
7/8
✓ Branch 0 taken 49803697 times.
✓ Branch 1 taken 324 times.
✓ Branch 2 taken 49802833 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 786 times.
✓ Branch 5 taken 49802047 times.
✓ Branch 6 taken 1409 times.
✓ Branch 7 taken 49801748 times.
49804021 if (flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK || thd_tablespace_op(thd))
5335 1409 return false;
5336
5337 // Add tablespace names used under partition/subpartition definitions.
5338
1/2
✓ Branch 0 taken 49804184 times.
✗ Branch 1 not taken.
49801748 Tablespace_hash_set tablespace_set(PSI_INSTRUMENT_ME);
5339 148794804 if ((thd->lex->sql_command == SQLCOM_CREATE_TABLE ||
5340
5/6
✓ Branch 0 taken 49186300 times.
✓ Branch 1 taken 617884 times.
✓ Branch 2 taken 85564 times.
✓ Branch 3 taken 49100736 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 49804320 times.
50507768 thd->lex->sql_command == SQLCOM_ALTER_TABLE) &&
5341
2/4
✓ Branch 0 taken 703584 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 703584 times.
703448 fill_partition_tablespace_names(thd->work_part_info, &tablespace_set))
5342 return true;
5343
5344 // The first step is to loop over the tables, make sure we have
5345 // locked the names, and then get hold of the tablespace names from
5346 // the data dictionary.
5347 TABLE_LIST *table;
5348
4/4
✓ Branch 0 taken 105696145 times.
✓ Branch 1 taken 49804295 times.
✓ Branch 2 taken 105695043 times.
✓ Branch 3 taken 1102 times.
155500440 for (table = tables_start; table && table != tables_end;
5349 105696120 table = table->next_global) {
5350 // Consider only non-temporary tables. The if clauses below have the
5351 // following meaning:
5352 //
5353 // !MDL_SHARED_READ_ONLY Not a LOCK TABLE ... READ.
5354 // In that case, tables will not
5355 // be altered, created or dropped,
5356 // so no need to IX lock the
5357 // tablespace.
5358 // is_ddl_or...request() || ...FOR_CREATE Request for a strong DDL or
5359 // LOCK TABLES type lock, or a
5360 // table to be created.
5361 // !OT_TEMPORARY_ONLY Not a user defined tmp table.
5362 // !(OT_TEMPORARY_OR_BASE && is_temp...()) Not a pre-opened tmp table.
5363
2/2
✓ Branch 0 taken 104792643 times.
✓ Branch 1 taken 602360 times.
105395003 if (table->mdl_request.type != MDL_SHARED_READ_ONLY &&
5364 105394628 (table->mdl_request.is_ddl_or_lock_tables_lock_request() ||
5365
2/2
✓ Branch 0 taken 617036 times.
✓ Branch 1 taken 104175607 times.
104792643 table->open_strategy == TABLE_LIST::OPEN_FOR_CREATE) &&
5366
8/8
✓ Branch 0 taken 105394628 times.
✓ Branch 1 taken 300415 times.
✓ Branch 2 taken 1132700 times.
✓ Branch 3 taken 87576 times.
✓ Branch 4 taken 1116569 times.
✓ Branch 5 taken 16131 times.
✓ Branch 6 taken 1116569 times.
✓ Branch 7 taken 104579729 times.
211090046 !is_temporary_table_being_opened(table) && !table->is_system_view) {
5367 // We have basically three situations here:
5368 //
5369 // 1. Lock only the target tablespace name and tablespace
5370 // names that are used by partitions (e.g. CREATE TABLE
5371 // explicitly specifying the tablespace names).
5372 // 2. Lock only the existing tablespace name and tablespace
5373 // names that are used by partitions (e.g. ALTER TABLE t
5374 // ADD COLUMN ... where t is defined in some tablespace s.
5375 // 3. Lock both the target and the existing tablespace names
5376 // along with tablespace names used by partitions. (e.g.
5377 // ALTER TABLE t TABLESPACE s2, where t is defined in
5378 // some tablespace s)
5379
2/2
✓ Branch 0 taken 350597 times.
✓ Branch 1 taken 765972 times.
1116569 if (table->target_tablespace_name.length > 0) {
5380
2/4
✓ Branch 0 taken 350597 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 350597 times.
✗ Branch 3 not taken.
350597 tablespace_set.insert(table->target_tablespace_name.str);
5381 }
5382
5383 // No need to try this for tables to be created since they are not
5384 // yet present in the dictionary.
5385
2/2
✓ Branch 0 taken 545495 times.
✓ Branch 1 taken 570897 times.
1116392 if (table->open_strategy != TABLE_LIST::OPEN_FOR_CREATE) {
5386 // Assert that we have an MDL lock on the table name. Needed to read
5387 // the dictionary safely.
5388
2/4
✓ Branch 0 taken 545495 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 545495 times.
545495 assert(thd->mdl_context.owns_equal_or_stronger_lock(
5389 MDL_key::TABLE, table->db, table->table_name, MDL_SHARED));
5390
5391 /*
5392 Add names of tablespaces used by table or by its
5393 partitions/subpartitions. Lookup data dictionary to get
5394 the information.
5395 */
5396
3/4
✓ Branch 0 taken 545495 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 545494 times.
545495 if (dd::fill_table_and_parts_tablespace_names(
5397 thd, table->db, table->table_name, &tablespace_set))
5398 1 return true;
5399 }
5400 }
5401 } // End of for(;;)
5402
5403 /*
5404 After we have identified the tablespace names, we iterate
5405 over the names and acquire IX locks on each of them.
5406 */
5407
5408
2/2
✓ Branch 0 taken 5105 times.
✓ Branch 1 taken 49800292 times.
49805397 if (thd->lex->sql_command == SQLCOM_DROP_DB) {
5409 /*
5410 In case of DROP DATABASE we might have to lock many thousands of
5411 tablespaces in extreme cases. Ensure that we don't hold memory used
5412 by corresponding MDL_requests after locks have been acquired to
5413 reduce memory usage by DROP DATABASE in such cases.
5414 */
5415 5105 MEM_ROOT mdl_reqs_root(key_memory_rm_db_mdl_reqs_root, MEM_ROOT_BLOCK_SIZE);
5416
5417
2/4
✓ Branch 0 taken 5105 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5105 times.
5105 if (lock_tablespace_names(thd, &tablespace_set, lock_wait_timeout,
5418 &mdl_reqs_root))
5419 return true;
5420
1/2
✓ Branch 0 taken 5105 times.
✗ Branch 1 not taken.
5105 } else {
5421
3/4
✓ Branch 0 taken 49796877 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 49796876 times.
49800292 if (lock_tablespace_names(thd, &tablespace_set, lock_wait_timeout,
5422 thd->mem_root))
5423 1 return true;
5424 }
5425
5426 49801981 return false;
5427 49801983 }
5428
5429 /**
5430 Acquire "strong" (SRO, SNW, SNRW) metadata locks on tables used by
5431 LOCK TABLES or by a DDL statement.
5432
5433 Acquire lock "S" on table being created in CREATE TABLE statement.
5434
5435 @note Under LOCK TABLES, we can't take new locks, so use
5436 open_tables_check_upgradable_mdl() instead.
5437
5438 @param thd Thread context.
5439 @param tables_start Start of list of tables on which locks
5440 should be acquired.
5441 @param tables_end End of list of tables.
5442 @param lock_wait_timeout Seconds to wait before timeout.
5443 @param flags Bitmap of flags to modify how the tables will be
5444 open, see open_table() description for details.
5445 @param schema_reqs When non-nullptr, pointer to array in which
5446 pointers to MDL requests for acquired schema
5447 locks to be stored. It is guaranteed that
5448 each schema will be present in this array
5449 only once.
5450
5451 @retval false Success.
5452 @retval true Failure (e.g. connection was killed)
5453 */
5454 49802578 bool lock_table_names(THD *thd, TABLE_LIST *tables_start,
5455 TABLE_LIST *tables_end, ulong lock_wait_timeout,
5456 uint flags,
5457 Prealloced_array<MDL_request *, 1> *schema_reqs) {
5458
1/2
✓ Branch 0 taken 49803104 times.
✗ Branch 1 not taken.
49802578 MDL_request_list mdl_requests;
5459 TABLE_LIST *table;
5460 49803104 MDL_request global_request;
5461 49802972 MDL_request backup_lock_request;
5462 malloc_unordered_set<TABLE_LIST *, schema_hash, schema_key_equal> schema_set(
5463
1/2
✓ Branch 0 taken 49803704 times.
✗ Branch 1 not taken.
49803481 PSI_INSTRUMENT_ME);
5464 49803704 bool need_global_read_lock_protection = false;
5465 49803704 bool acquire_backup_lock = false;
5466 49803704 MDL_request percona_backup_request;
5467
5468 /*
5469 This function is not supposed to be used under LOCK TABLES normally.
5470 Instead open_tables_check_upgradable_mdl() or some other function
5471 checking if we have tables locked in proper mode should be used.
5472
5473 The exception to this rule is RENAME TABLES code which uses this call
5474 to "upgrade" metadata lock on tables renamed along with acquiring
5475 exclusive locks on target table names, after checking that tables
5476 renamed are properly locked.
5477 */
5478
3/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 49804513 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28 times.
49804541 assert(!thd->locked_tables_mode ||
5479 thd->lex->sql_command == SQLCOM_RENAME_TABLE);
5480
5481 // Phase 1: Iterate over tables, collect set of unique schema names, and
5482 // construct a list of requests for table MDL locks.
5483
4/4
✓ Branch 0 taken 105697597 times.
✓ Branch 1 taken 49804495 times.
✓ Branch 2 taken 105696631 times.
✓ Branch 3 taken 966 times.
155502092 for (table = tables_start; table && table != tables_end;
5484 105697551 table = table->next_global) {
5485
2/2
✓ Branch 0 taken 331765 times.
✓ Branch 1 taken 105365286 times.
105696631 if (is_temporary_table_being_opened(table)) {
5486 331765 continue;
5487 }
5488
5489
4/4
✓ Branch 0 taken 104501172 times.
✓ Branch 1 taken 864053 times.
✓ Branch 2 taken 103930635 times.
✓ Branch 3 taken 1434590 times.
209866458 if (!table->mdl_request.is_ddl_or_lock_tables_lock_request() &&
5490
2/2
✓ Branch 0 taken 103930526 times.
✓ Branch 1 taken 570646 times.
104501172 table->open_strategy != TABLE_LIST::OPEN_FOR_CREATE) {
5491 103930635 continue;
5492 } else {
5493 /*
5494 MDL_request::is_ddl_or_lock_tables_lock_request() returns true for
5495 DDL and LOCK TABLES statements. Since there isn't a way on MDL API level
5496 to determine whether a lock being acquired is requested as part of
5497 handling the statement LOCK TABLES, such check will be done by comparing
5498 a value of lex->sql_command against the constant SQLCOM_LOCK_TABLES.
5499 Also we shouldn't acquire IX backup lock in case a table being opened
5500 with requested MDL_SHARED_READ_ONLY lock. For example, such use case
5501 takes place when FLUSH PRIVILEGES executed.
5502 */
5503
2/2
✓ Branch 0 taken 1432086 times.
✓ Branch 1 taken 2504 times.
1434590 if (thd->lex->sql_command != SQLCOM_LOCK_TABLES &&
5504
2/2
✓ Branch 0 taken 1131568 times.
✓ Branch 1 taken 300518 times.
1432086 table->mdl_request.type != MDL_SHARED_READ_ONLY)
5505 1131568 acquire_backup_lock = true;
5506 }
5507
5508
2/2
✓ Branch 0 taken 1133133 times.
✓ Branch 1 taken 301457 times.
1434590 if (table->mdl_request.type != MDL_SHARED_READ_ONLY) {
5509 /* Write lock on normal tables is not allowed in a read only transaction.
5510 */
5511
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1133132 times.
1133133 if (thd->tx_read_only) {
5512
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0));
5513 1 return true;
5514 }
5515
5516
2/2
✓ Branch 0 taken 1132600 times.
✓ Branch 1 taken 532 times.
1133132 if (!(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK)) {
5517
1/2
✓ Branch 0 taken 1132600 times.
✗ Branch 1 not taken.
1132600 schema_set.insert(table);
5518 }
5519 1133132 need_global_read_lock_protection = true;
5520 }
5521
5522
1/2
✓ Branch 0 taken 1435151 times.
✗ Branch 1 not taken.
1434589 mdl_requests.push_front(&table->mdl_request);
5523 }
5524
5525 // Phase 2: Iterate over the schema set, add an IX lock for each
5526 // schema name.
5527
6/6
✓ Branch 0 taken 49803323 times.
✓ Branch 1 taken 2138 times.
✓ Branch 2 taken 1088991 times.
✓ Branch 3 taken 48714103 times.
✓ Branch 4 taken 1088991 times.
✓ Branch 5 taken 48716241 times.
49805461 if (!(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) && !mdl_requests.is_empty()) {
5528 /*
5529 Scoped locks: Take intention exclusive locks on all involved
5530 schemas.
5531 */
5532
2/2
✓ Branch 0 taken 1062101 times.
✓ Branch 1 taken 1088991 times.
2151092 for (const TABLE_LIST *table_l : schema_set) {
5533
1/2
✓ Branch 0 taken 1062101 times.
✗ Branch 1 not taken.
1062101 MDL_request *schema_request = new (thd->mem_root) MDL_request;
5534
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1062101 times.
1062101 if (schema_request == nullptr) return true;
5535
1/2
✓ Branch 0 taken 1062101 times.
✗ Branch 1 not taken.
1062101 MDL_REQUEST_INIT(schema_request, MDL_key::SCHEMA, table_l->db, "",
5536 MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION);
5537
1/2
✓ Branch 0 taken 1062101 times.
✗ Branch 1 not taken.
1062101 mdl_requests.push_front(schema_request);
5538
3/4
✓ Branch 0 taken 33279 times.
✓ Branch 1 taken 1028822 times.
✓ Branch 2 taken 33279 times.
✗ Branch 3 not taken.
1062101 if (schema_reqs) schema_reqs->push_back(schema_request);
5539 }
5540
5541
2/2
✓ Branch 0 taken 1038743 times.
✓ Branch 1 taken 50248 times.
1088991 if (need_global_read_lock_protection) {
5542 /*
5543 Protect this statement against concurrent global read lock
5544 by acquiring global intention exclusive lock with statement
5545 duration.
5546 */
5547
3/4
✓ Branch 0 taken 1038743 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 1038713 times.
1038743 if (thd->global_read_lock.can_acquire_protection()) return true;
5548
1/2
✓ Branch 0 taken 1038713 times.
✗ Branch 1 not taken.
1038713 MDL_REQUEST_INIT(&global_request, MDL_key::GLOBAL, "", "",
5549 MDL_INTENTION_EXCLUSIVE, MDL_STATEMENT);
5550
1/2
✓ Branch 0 taken 1038713 times.
✗ Branch 1 not taken.
1038713 mdl_requests.push_front(&global_request);
5551
5552
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1038713 times.
1038713 if (thd->backup_tables_lock.abort_if_acquired()) return true;
5553
1/2
✓ Branch 0 taken 1038713 times.
✗ Branch 1 not taken.
1038713 thd->backup_tables_lock.init_protection_request(&percona_backup_request,
5554 MDL_STATEMENT);
5555
1/2
✓ Branch 0 taken 1038713 times.
✗ Branch 1 not taken.
1038713 mdl_requests.push_front(&percona_backup_request);
5556 }
5557 }
5558
5559
2/2
✓ Branch 0 taken 1037829 times.
✓ Branch 1 taken 48767373 times.
49805202 if (acquire_backup_lock) {
5560
1/2
✓ Branch 0 taken 1037829 times.
✗ Branch 1 not taken.
1037829 MDL_REQUEST_INIT(&backup_lock_request, MDL_key::BACKUP_LOCK, "", "",
5561 MDL_INTENTION_EXCLUSIVE, MDL_TRANSACTION);
5562
1/2
✓ Branch 0 taken 1037829 times.
✗ Branch 1 not taken.
1037829 mdl_requests.push_front(&backup_lock_request);
5563 }
5564
5565 // Phase 3: Acquire the locks which have been requested so far.
5566
3/4
✓ Branch 0 taken 49802326 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 214 times.
✓ Branch 3 taken 49802112 times.
49805202 if (thd->mdl_context.acquire_locks(&mdl_requests, lock_wait_timeout))
5567 214 return true;
5568
5569 /*
5570 Now when we have protection against concurrent change of read_only
5571 option we can safely re-check its value. Skip the check for
5572 FLUSH TABLES ... WITH READ LOCK and FLUSH TABLES ... FOR EXPORT
5573 as they are not supposed to be affected by read_only modes.
5574 */
5575 50841189 if (need_global_read_lock_protection &&
5576
2/2
✓ Branch 0 taken 1038594 times.
✓ Branch 1 taken 482 times.
1039076 !(flags & MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK) &&
5577
5/6
✓ Branch 0 taken 1039076 times.
✓ Branch 1 taken 48763036 times.
✓ Branch 2 taken 1038594 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✓ Branch 5 taken 49802098 times.
51879783 !(flags & MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY) &&
5578
3/4
✓ Branch 0 taken 1038595 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✓ Branch 3 taken 1038580 times.
1038594 check_readonly(thd, true))
5579 15 return true;
5580
5581 // Check schema read only for all schemas.
5582
2/2
✓ Branch 0 taken 1061934 times.
✓ Branch 1 taken 49803056 times.
50864006 for (const TABLE_LIST *table_l : schema_set)
5583
3/4
✓ Branch 0 taken 1061936 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 1061908 times.
1061935 if (check_schema_readonly(thd, table_l->db)) return true;
5584
5585 /*
5586 Phase 4: Lock tablespace names. This cannot be done as part
5587 of the previous phases, because we need to read the
5588 dictionary to get hold of the tablespace name, and in order
5589 to do this, we must have acquired a lock on the table.
5590 */
5591
1/2
✓ Branch 0 taken 49803940 times.
✗ Branch 1 not taken.
49803056 return get_and_lock_tablespace_names(thd, tables_start, tables_end,
5592 49803940 lock_wait_timeout, flags);
5593 49804228 }
5594
5595 /**
5596 Check for upgradable (SNW, SNRW) metadata locks on tables to be opened
5597 for a DDL statement. Under LOCK TABLES, we can't take new locks, so we
5598 must check if appropriate locks were pre-acquired.
5599
5600 @param thd Thread context.
5601 @param tables_start Start of list of tables on which upgradable locks
5602 should be searched for.
5603 @param tables_end End of list of tables.
5604
5605 @retval false Success.
5606 @retval true Failure (e.g. connection was killed)
5607 */
5608
5609 831856 static bool open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
5610 TABLE_LIST *tables_end) {
5611 TABLE_LIST *table;
5612
5613
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 831856 times.
831856 assert(thd->locked_tables_mode);
5614
5615
4/4
✓ Branch 0 taken 82575 times.
✓ Branch 1 taken 831820 times.
✓ Branch 2 taken 82574 times.
✓ Branch 3 taken 1 times.
914395 for (table = tables_start; table && table != tables_end;
5616 82539 table = table->next_global) {
5617
6/6
✓ Branch 0 taken 1351 times.
✓ Branch 1 taken 81223 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1345 times.
✓ Branch 4 taken 81229 times.
✓ Branch 5 taken 1345 times.
83925 if (!table->mdl_request.is_ddl_or_lock_tables_lock_request() ||
5618 1351 is_temporary_table_being_opened(table)) {
5619 81229 continue;
5620 }
5621
5622
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1343 times.
1345 if (table->mdl_request.type == MDL_SHARED_READ_ONLY) {
5623
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (!thd->mdl_context.owns_equal_or_stronger_lock(
5624 MDL_key::TABLE, table->db, table->table_name,
5625 MDL_SHARED_READ_ONLY)) {
5626 2 my_error(ER_TABLE_NOT_LOCKED, MYF(0), table->table_name);
5627 2 return true;
5628 }
5629 } else {
5630 /*
5631 We don't need to do anything about the found TABLE instance as it
5632 will be handled later in open_tables(), we only need to check that
5633 an upgradable lock is already acquired. When we enter LOCK TABLES
5634 mode, SNRW locks are acquired before all other locks. So if under
5635 LOCK TABLES we find that there is TABLE instance with upgradeable
5636 lock, all other instances of TABLE for the same table will have the
5637 same ticket.
5638
5639 Note that this works OK even for CREATE TABLE statements which
5640 request X type of metadata lock. This is because under LOCK TABLES
5641 such statements don't create the table but only check if it exists
5642 or, in most complex case, only insert into it.
5643 Thus SNRW lock should be enough.
5644
5645 Note that find_table_for_mdl_upgrade() will report an error if
5646 no suitable ticket is found.
5647 */
5648
2/2
✓ Branch 0 taken 33 times.
✓ Branch 1 taken 1310 times.
1343 if (!find_table_for_mdl_upgrade(thd, table->db, table->table_name, false))
5649 33 return true;
5650 }
5651 }
5652
5653 831821 return false;
5654 }
5655
5656 /**
5657 Iterate along a list of tables and acquire BACKUP LOCK in shared mode
5658 in case a strong MDL request (DDL/LOCK TABLES-type) was specified
5659 for a table.
5660
5661 @param[in] thd Thread context.
5662 @param[in] tables_start Pointer to a start of a list of tables to iterate
5663 @param[in] tables_end Pointer to a end of a list of tables where to stop
5664
5665 @return false on success, true on error.
5666 */
5667
5668 831821 static bool acquire_backup_lock_in_lock_tables_mode(THD *thd,
5669 TABLE_LIST *tables_start,
5670 TABLE_LIST *tables_end) {
5671 TABLE_LIST *table;
5672
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 831821 times.
831821 assert(thd->locked_tables_mode);
5673
5674
4/4
✓ Branch 0 taken 82528 times.
✓ Branch 1 taken 830522 times.
✓ Branch 2 taken 82527 times.
✓ Branch 3 taken 1 times.
913050 for (table = tables_start; table && table != tables_end;
5675 81229 table = table->next_global) {
5676
2/2
✓ Branch 0 taken 1338 times.
✓ Branch 1 taken 81189 times.
82527 if (is_temporary_table_being_opened(table)) continue;
5677
5678
4/4
✓ Branch 0 taken 1298 times.
✓ Branch 1 taken 79891 times.
✓ Branch 2 taken 1298 times.
✓ Branch 3 taken 79891 times.
82487 if (table->mdl_request.is_ddl_or_lock_tables_lock_request() &&
5679
1/2
✓ Branch 0 taken 1298 times.
✗ Branch 1 not taken.
1298 table->mdl_request.type != MDL_SHARED_READ_ONLY)
5680 1298 return acquire_shared_backup_lock(thd, thd->variables.lock_wait_timeout);
5681 }
5682
5683 830523 return false;
5684 }
5685
5686 /**
5687 Check if this is a DD table used under a I_S view then request InnoDB to
5688 do non-locking reads on the table.
5689
5690 @param thd Thread
5691 @param[in] tl TABLE_LIST pointing to table being checked.
5692
5693 @return false on success, true on error.
5694 */
5695
5696 108399805 static bool set_non_locking_read_for_IS_view(THD *thd, TABLE_LIST *tl) {
5697 108399805 TABLE *tbl = tl->table;
5698
5699 // Not a system view.
5700
6/6
✓ Branch 0 taken 106919567 times.
✓ Branch 1 taken 1480238 times.
✓ Branch 2 taken 106916314 times.
✓ Branch 3 taken 3253 times.
✓ Branch 4 taken 2625993 times.
✓ Branch 5 taken 104290321 times.
108399805 if (!(tbl && tbl->file && tl->referencing_view &&
5701
2/2
✓ Branch 0 taken 224033 times.
✓ Branch 1 taken 2401960 times.
2625993 tl->referencing_view->is_system_view))
5702 105997845 return false;
5703
5704 // Allow I_S system views to be locked by LOCK TABLE command.
5705
3/4
✓ Branch 0 taken 2400717 times.
✓ Branch 1 taken 1243 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2401960 times.
4802677 if (thd->lex->sql_command != SQLCOM_LOCK_TABLES &&
5706
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2400717 times.
2400717 tl->lock_descriptor().type >= TL_READ_NO_INSERT) {
5707 my_error(ER_IS_QUERY_INVALID_CLAUSE, MYF(0), "FOR UPDATE");
5708 return true;
5709 }
5710
5711 /* Convey to InnoDB (the DD table's engine) to do non-locking reads.
5712
5713 It is assumed that all the tables used by I_S views are
5714 always a DD table. If this is not true, then we might
5715 need to invoke dd::Dictionary::is_dd_tablename() to make sure.
5716 */
5717
5718 /* Addition to the above upstream comment:
5719 Compression_dictionary table is dd::System_tables::Types::SYSTEM, so
5720 pushing HA_EXTRA_NO_READ_LOCKING down will cause the assert in ha_innodb.cc
5721 line c.a. 19297 (no_read_locking == true, is_dd_table == false).
5722 This is the logic in ha_innobase::external_lock introduced in 8.0.22.
5723 Below causes HA_EXTRA_NO_READ_LOCKING not to be pushed for SYSTEM tables
5724 and we have locking as before.
5725 */
5726
3/6
✓ Branch 0 taken 2401949 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2401947 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2401927 times.
✗ Branch 5 not taken.
2401960 bool is_dd_table = dd::get_dictionary()->is_dd_table_name(
5727 tl->get_db_name(), tl->get_table_name());
5728
5/6
✓ Branch 0 taken 2358976 times.
✓ Branch 1 taken 42986 times.
✓ Branch 2 taken 2355949 times.
✓ Branch 3 taken 3027 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2401970 times.
4757919 if (is_dd_table && tbl->db_stat &&
5729
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2355957 times.
2355949 tbl->file->ha_extra(HA_EXTRA_NO_READ_LOCKING)) {
5730 // Handler->ha_extra() for innodb does not fail ever as of now.
5731 // In case it is made to fail sometime later, we need to think
5732 // about the kind of error to be report to user.
5733 assert(0);
5734 return true;
5735 }
5736
5737 2401970 return false;
5738 }
5739
5740 // Check if given TABLE_LIST is a acl table and is being read and not
5741 110393099 bool is_acl_table_in_non_LTM(const TABLE_LIST *tl,
5742 enum enum_locked_tables_mode ltm) {
5743 110393099 TABLE *table = tl->table;
5744
5745 /**
5746 We ignore use of ACL table,
5747 - Under LOCK TABLE modes.
5748 - Under system view. E.g., I_S.ROLE_* uses CTE where they use
5749 TL_READ_DEFAULT for ACL tables. We ignore them.
5750 - If the TABLE_LIST is used by optimizer as placeholder.
5751 */
5752
2/2
✓ Branch 0 taken 108327398 times.
✓ Branch 1 taken 150508 times.
218871005 return (!tl->is_placeholder() && table->db_stat &&
5753
4/4
✓ Branch 0 taken 1854132 times.
✓ Branch 1 taken 106473266 times.
✓ Branch 2 taken 1853648 times.
✓ Branch 3 taken 484 times.
108327398 table->s->table_category == TABLE_CATEGORY_ACL_TABLE &&
5754
3/4
✓ Branch 0 taken 108477906 times.
✓ Branch 1 taken 1916221 times.
✓ Branch 2 taken 1853648 times.
✗ Branch 3 not taken.
218872033 ltm != LTM_LOCK_TABLES && ltm != LTM_PRELOCKED_UNDER_LOCK_TABLES);
5755 }
5756
5757 /**
5758 Check if this is a ACL table is requested for read and
5759 then request InnoDB to do non-locking reads on the
5760 table.
5761
5762 @param thd Thread
5763 @param[in] tl TABLE_LIST pointing to table being checked.
5764 @param[in] issue_warning If true, issue warning irrespective of
5765 isolation level.
5766
5767 @return false on success, true on error.
5768 */
5769
5770 108342070 static bool set_non_locking_read_for_ACL_table(THD *thd, TABLE_LIST *tl,
5771 const bool &issue_warning) {
5772 108342070 TABLE *tbl = tl->table;
5773
5774 /*
5775 Request InnoDB to skip SE row locks if:
5776 - We have a ACL table name.
5777 - Lock type is TL_READ_DEFAULT or
5778 - Lock type is TL_READ_HIGH_PRIORITY.
5779
5780 Note:
5781 - We do this for all isolation modes as InnoDB sometimes acquires row
5782 locks even for modes other than serializable, e.g. to ensure correct
5783 binlogging or just to play safe.
5784
5785 - Checking only for TL_READ_DEFAULT and TL_READ_HIGH_PRIORITY allows to
5786 filter out all special non-SELECT cases which require locking like
5787 ALTER TABLE, ACL DDL and so on
5788 */
5789
4/4
✓ Branch 0 taken 1449070 times.
✓ Branch 1 taken 106893796 times.
✓ Branch 2 taken 36504 times.
✓ Branch 3 taken 108306397 times.
109791175 if (is_acl_table_in_non_LTM(tl, thd->locked_tables_mode) &&
5790
2/2
✓ Branch 0 taken 1412535 times.
✓ Branch 1 taken 36535 times.
1449070 (tl->lock_descriptor().type == TL_READ_DEFAULT ||
5791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1412601 times.
1412535 tl->lock_descriptor().type == TL_READ_HIGH_PRIORITY)) {
5792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36504 times.
36504 if (tbl->file->ha_extra(HA_EXTRA_NO_READ_LOCKING)) {
5793 /*
5794 Handler->ha_extra() for InnoDB does not fail ever as of now. In
5795 case it is made to fail sometime later, we need to think about the
5796 kind of error to be report to user.
5797 */
5798 assert(0);
5799 return true;
5800 }
5801
5802 /**
5803 Issue a warning when,
5804 - We are skipping the SE locks in serializable
5805 - We are skipping the SE locks for SELECT IN SHARE MODE in all
5806 isolation mode.
5807 - When ACL table is not used under I_S system view.
5808 */
5809
4/4
✓ Branch 0 taken 36337 times.
✓ Branch 1 taken 167 times.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 36306 times.
36504 if ((thd->tx_isolation == ISO_SERIALIZABLE || issue_warning) &&
5810
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 194 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
198 !(tl->referencing_view && tl->referencing_view->is_system_view))
5811 194 push_warning(thd, Sql_condition::SL_WARNING,
5812 WARN_UNSUPPORTED_ACL_TABLES_READ,
5813 ER_THD(thd, WARN_UNSUPPORTED_ACL_TABLES_READ));
5814 }
5815
5816 108342812 return false;
5817 }
5818
5819 /**
5820 Open all tables in list
5821
5822 @param[in] thd Thread context.
5823 @param[in,out] start List of tables to be open (it can be adjusted for
5824 statement that uses tables only implicitly, e.g.
5825 for "SELECT f1()").
5826 @param[out] counter Number of tables which were open.
5827 @param[in] flags Bitmap of flags to modify how the tables will be
5828 open, see open_table() description for details.
5829 @param[in] prelocking_strategy Strategy which specifies how prelocking
5830 algorithm should work for this statement.
5831
5832 @note
5833 Unless we are already in prelocked mode and prelocking strategy prescribes
5834 so this function will also precache all SP/SFs explicitly or implicitly
5835 (via views and triggers) used by the query and add tables needed for their
5836 execution to table list. Statement that uses SFs, invokes triggers or
5837 requires foreign key checks will be marked as requiring prelocking.
5838 Prelocked mode will be enabled for such query during lock_tables() call.
5839
5840 If query for which we are opening tables is already marked as requiring
5841 prelocking it won't do such precaching and will simply reuse table list
5842 which is already built.
5843
5844 @retval false Success.
5845 @retval true Error, reported.
5846 */
5847
5848 50584484 bool open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags,
5849 Prelocking_strategy *prelocking_strategy) {
5850 /*
5851 We use pointers to "next_global" member in the last processed TABLE_LIST
5852 element and to the "next" member in the last processed Sroutine_hash_entry
5853 element as iterators over, correspondingly, the table list and stored
5854 routines list which stay valid and allow to continue iteration when new
5855 elements are added to the tail of the lists.
5856 */
5857 TABLE_LIST **table_to_open;
5858 TABLE *old_table;
5859 Sroutine_hash_entry **sroutine_to_open;
5860 TABLE_LIST *tables;
5861
1/2
✓ Branch 0 taken 50586201 times.
✗ Branch 1 not taken.
50584484 Open_table_context ot_ctx(thd, flags);
5862 50586201 bool error = false;
5863 50586201 bool some_routine_modifies_data = false;
5864 bool has_prelocking_list;
5865
1/2
✓ Branch 0 taken 50586198 times.
✗ Branch 1 not taken.
50586201 DBUG_TRACE;
5866 50586198 bool audit_notified = false;
5867
5868 50586232 restart:
5869 /*
5870 Close HANDLER tables which are marked for flush or against which there
5871 are pending exclusive metadata locks. This is needed both in order to
5872 avoid deadlocks and to have a point during statement execution at
5873 which such HANDLERs are closed even if they don't create problems for
5874 the current session (i.e. to avoid having a DDL blocked by HANDLERs
5875 opened for a long time).
5876 */
5877
3/4
✓ Branch 0 taken 1661 times.
✓ Branch 1 taken 50583936 times.
✓ Branch 2 taken 1661 times.
✗ Branch 3 not taken.
50586232 if (!thd->handler_tables_hash.empty()) mysql_ha_flush(thd);
5878
5879 50585597 has_prelocking_list = thd->lex->requires_prelocking();
5880 50585661 table_to_open = start;
5881
2/2
✓ Branch 0 taken 33392438 times.
✓ Branch 1 taken 17193223 times.
50585661 old_table = *table_to_open ? (*table_to_open)->table : nullptr;
5882 50585661 sroutine_to_open = &thd->lex->sroutines_list.first;
5883 50585661 *counter = 0;
5884
5885
2/2
✓ Branch 0 taken 29353582 times.
✓ Branch 1 taken 21232079 times.
50585661 if (!(thd->state_flags & Open_tables_state::SYSTEM_TABLES))
5886
1/2
✓ Branch 0 taken 29351225 times.
✗ Branch 1 not taken.
29353582 THD_STAGE_INFO(thd, stage_opening_tables);
5887
5888 /*
5889 If we are executing LOCK TABLES statement or a DDL statement
5890 (in non-LOCK TABLES mode) we might have to acquire upgradable
5891 semi-exclusive metadata locks (SNW or SNRW) on some of the
5892 tables to be opened.
5893 When executing CREATE TABLE .. If NOT EXISTS .. SELECT, the
5894 table may not yet exist, in which case we acquire an exclusive
5895 lock.
5896 We acquire all such locks at once here as doing this in one
5897 by one fashion may lead to deadlocks or starvation. Later when
5898 we will be opening corresponding table pre-acquired metadata
5899 lock will be reused (thanks to the fact that in recursive case
5900 metadata locks are acquired without waiting).
5901 */
5902
2/2
✓ Branch 0 taken 50404960 times.
✓ Branch 1 taken 178344 times.
50583304 if (!(flags & (MYSQL_OPEN_HAS_MDL_LOCK | MYSQL_OPEN_FORCE_SHARED_MDL |
5903 MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL))) {
5904
2/2
✓ Branch 0 taken 831856 times.
✓ Branch 1 taken 49573104 times.
50404960 if (thd->locked_tables_mode) {
5905 /*
5906 Under LOCK TABLES, we can't acquire new locks, so we instead
5907 need to check if appropriate locks were pre-acquired.
5908 */
5909 831856 TABLE_LIST *end_table = thd->lex->first_not_own_table();
5910
5/6
✓ Branch 0 taken 831856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 831821 times.
✓ Branch 3 taken 35 times.
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 831821 times.
1663677 if (open_tables_check_upgradable_mdl(thd, *start, end_table) ||
5911
2/4
✓ Branch 0 taken 831821 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 831821 times.
831821 acquire_backup_lock_in_lock_tables_mode(thd, *start, end_table)) {
5912 35 error = true;
5913 35 goto err;
5914 }
5915 } else {
5916 TABLE_LIST *table;
5917
3/4
✓ Branch 0 taken 49573841 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 207 times.
✓ Branch 3 taken 49573634 times.
49573104 if (lock_table_names(thd, *start, thd->lex->first_not_own_table(),
5918 ot_ctx.get_timeout(), flags)) {
5919 207 error = true;
5920 207 goto err;
5921 }
5922
6/6
✓ Branch 0 taken 105373484 times.
✓ Branch 1 taken 49573898 times.
✓ Branch 2 taken 105373673 times.
✓ Branch 3 taken 1129 times.
✓ Branch 4 taken 105373747 times.
✓ Branch 5 taken 49574953 times.
154947382 for (table = *start; table && table != thd->lex->first_not_own_table();
5923 105373748 table = table->next_global) {
5924
4/4
✓ Branch 0 taken 104792819 times.
✓ Branch 1 taken 580929 times.
✓ Branch 2 taken 1198848 times.
✓ Branch 3 taken 104174900 times.
210166566 if (table->mdl_request.is_ddl_or_lock_tables_lock_request() ||
5925
2/2
✓ Branch 0 taken 617791 times.
✓ Branch 1 taken 104175028 times.
104792819 table->open_strategy == TABLE_LIST::OPEN_FOR_CREATE)
5926 1198848 table->mdl_request.ticket = nullptr;
5927 }
5928 }
5929 }
5930
5931 /*
5932 Perform steps of prelocking algorithm until there are unprocessed
5933 elements in prelocking list/set.
5934 */
5935
2/2
✓ Branch 0 taken 33416010 times.
✓ Branch 1 taken 50692781 times.
84108791 while (*table_to_open ||
5936
4/4
✓ Branch 0 taken 49899532 times.
✓ Branch 1 taken 793249 times.
✓ Branch 2 taken 170090 times.
✓ Branch 3 taken 49729442 times.
50692781 (thd->locked_tables_mode <= LTM_LOCK_TABLES && *sroutine_to_open)) {
5937 /*
5938 For every table in the list of tables to open, try to find or open
5939 a table.
5940 */
5941
2/2
✓ Branch 0 taken 108492037 times.
✓ Branch 1 taken 33524447 times.
142016484 for (tables = *table_to_open; tables;
5942 108430384 table_to_open = &tables->next_global, tables = tables->next_global) {
5943 108492037 old_table = (*table_to_open)->table;
5944
1/2
✓ Branch 0 taken 108493607 times.
✗ Branch 1 not taken.
108492037 error = open_and_process_table(thd, thd->lex, tables, counter,
5945 prelocking_strategy, has_prelocking_list,
5946 &ot_ctx);
5947
5948
2/2
✓ Branch 0 taken 63540 times.
✓ Branch 1 taken 108430067 times.
108493607 if (error) {
5949
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 63503 times.
63540 if (ot_ctx.can_recover_from_failed_open()) {
5950 /*
5951 We have met exclusive metadata lock or old version of table.
5952 Now we have to close all tables and release metadata locks.
5953 We also have to throw away set of prelocked tables (and thus
5954 close tables from this set that were open by now) since it
5955 is possible that one of tables which determined its content
5956 was changed.
5957
5958 Instead of implementing complex/non-robust logic mentioned
5959 above we simply close and then reopen all tables.
5960
5961 We have to save pointer to table list element for table which we
5962 have failed to open since closing tables can trigger removal of
5963 elements from the table list (if MERGE tables are involved),
5964 */
5965
1/2
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
38 close_tables_for_reopen(thd, start, ot_ctx.start_of_statement_svp());
5966
5967 /*
5968 Here we rely on the fact that 'tables' still points to the valid
5969 TABLE_LIST element. Although currently this assumption is valid
5970 it may change in future.
5971 */
5972
3/4
✓ Branch 0 taken 35 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 34 times.
35 if (ot_ctx.recover_from_failed_open()) goto err;
5973
5974 /* Re-open temporary tables after close_tables_for_reopen(). */
5975
2/4
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 34 times.
34 if (open_temporary_tables(thd, *start)) goto err;
5976
5977 34 error = false;
5978 34 goto restart;
5979 }
5980 63503 goto err;
5981 }
5982
5983
3/4
✓ Branch 0 taken 99469843 times.
✓ Branch 1 taken 8959788 times.
✓ Branch 2 taken 99470596 times.
✗ Branch 3 not taken.
108430067 DEBUG_SYNC(thd, "open_tables_after_open_and_process_table");
5984 }
5985
5986 /*
5987 Iterate through set of tables and generate table access audit events.
5988 */
5989
7/8
✓ Branch 0 taken 33500827 times.
✓ Branch 1 taken 23620 times.
✓ Branch 2 taken 33500199 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 33500186 times.
✓ Branch 6 taken 13 times.
✓ Branch 7 taken 33523806 times.
33524447 if (!audit_notified && mysql_audit_table_access_notify(thd, *start)) {
5990 13 error = true;
5991 13 goto err;
5992 }
5993
5994 /*
5995 Event is not generated in the next loop. It may contain duplicated
5996 table entries as well as new tables discovered for stored procedures.
5997 Events for these tables will be generated during the queries of these
5998 stored procedures.
5999 */
6000 33523806 audit_notified = true;
6001
6002 /*
6003 If we are not already in prelocked mode and extended table list is
6004 not yet built for our statement we need to cache routines it uses
6005 and build the prelocking list for it.
6006 If we are not in prelocked mode but have built the extended table
6007 list, we still need to call open_and_process_routine() to take
6008 MDL locks on the routines.
6009 */
6010
2/2
✓ Branch 0 taken 33470910 times.
✓ Branch 1 taken 52896 times.
33523806 if (thd->locked_tables_mode <= LTM_LOCK_TABLES) {
6011 bool routine_modifies_data;
6012 /*
6013 Process elements of the prelocking set which are present there
6014 since parsing stage or were added to it by invocations of
6015 Prelocking_strategy methods in the above loop over tables.
6016
6017 For example, if element is a routine, cache it and then,
6018 if prelocking strategy prescribes so, add tables it uses to the
6019 table list and routines it might invoke to the prelocking set.
6020 */
6021
2/2
✓ Branch 0 taken 4223364 times.
✓ Branch 1 taken 33470777 times.
37694141 for (Sroutine_hash_entry *rt = *sroutine_to_open; rt;
6022 4223231 sroutine_to_open = &rt->next, rt = rt->next) {
6023 4223364 bool need_prelocking = false;
6024 4223364 TABLE_LIST **save_query_tables_last = thd->lex->query_tables_last;
6025
6026
1/2
✓ Branch 0 taken 4223366 times.
✗ Branch 1 not taken.
4223364 error = open_and_process_routine(
6027
1/2
✓ Branch 0 taken 4223364 times.
✗ Branch 1 not taken.
4223364 thd, thd->lex, rt, prelocking_strategy, has_prelocking_list,
6028 &ot_ctx, &need_prelocking, &routine_modifies_data);
6029
6030
6/6
✓ Branch 0 taken 115628 times.
✓ Branch 1 taken 4107738 times.
✓ Branch 2 taken 20036 times.
✓ Branch 3 taken 95592 times.
✓ Branch 4 taken 20036 times.
✓ Branch 5 taken 4203330 times.
4223366 if (need_prelocking && !thd->lex->requires_prelocking())
6031 20036 thd->lex->mark_as_requiring_prelocking(save_query_tables_last);
6032
6033
4/4
✓ Branch 0 taken 115628 times.
✓ Branch 1 taken 4107738 times.
✓ Branch 2 taken 34864 times.
✓ Branch 3 taken 80764 times.
4223366 if (need_prelocking && !*start) *start = thd->lex->query_tables;
6034
6035
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 4223231 times.
4223366 if (error) {
6036
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 135 times.
135 if (ot_ctx.can_recover_from_failed_open()) {
6037 close_tables_for_reopen(thd, start,
6038 ot_ctx.start_of_statement_svp());
6039
0/4
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
135 if (ot_ctx.recover_from_failed_open()) goto err;
6040
6041 /* Re-open temporary tables after close_tables_for_reopen(). */
6042 if (open_temporary_tables(thd, *start)) goto err;
6043
6044 error = false;
6045 goto restart;
6046 }
6047 /*
6048 Serious error during reading stored routines from mysql.proc table.
6049 Something is wrong with the table or its contents, and an error has
6050 been emitted; we must abort.
6051 */
6052 135 goto err;
6053 }
6054
6055 // Remember if any of SF modifies data.
6056 4223231 some_routine_modifies_data |= routine_modifies_data;
6057 }
6058 }
6059 }
6060
6061 /* Accessing data in XA_IDLE or XA_PREPARED is not allowed. */
6062
4/4
✓ Branch 0 taken 33331958 times.
✓ Branch 1 taken 17190733 times.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 50521337 times.
83853311 if (*start &&
6063
2/4
✓ Branch 0 taken 33331435 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33331457 times.
✗ Branch 3 not taken.
33331958 (thd->get_transaction()->xid_state()->check_xa_idle_or_prepared(true) ||
6064
3/4
✓ Branch 0 taken 33330642 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 38 times.
✓ Branch 3 taken 33330604 times.
33331457 thd->get_transaction()->xid_state()->xa_trans_rolled_back()))
6065 16 return true;
6066
6067 /*
6068 If some routine is modifying the table then the statement is not read only.
6069 If timer is enabled then resetting the timer in this case.
6070 */
6071
4/4
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 50521208 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 128 times.
50521337 if (thd->timer && some_routine_modifies_data) {
6072
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 reset_statement_timer(thd);
6073
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 336 times.
✗ Branch 3 not taken.
1 push_warning(thd, Sql_condition::SL_NOTE, ER_NON_RO_SELECT_DISABLE_TIMER,
6074 ER_THD(thd, ER_NON_RO_SELECT_DISABLE_TIMER));
6075 }
6076
6077 /*
6078 After successful open of all tables, including MERGE parents and
6079 children, attach the children to their parents. At end of statement,
6080 the children are detached. Attaching and detaching are always done,
6081 even under LOCK TABLES.
6082
6083 We also convert all TL_WRITE_DEFAULT and TL_READ_DEFAULT locks to
6084 appropriate "real" lock types to be used for locking and to be passed
6085 to storage engine.
6086 */
6087
2/2
✓ Branch 0 taken 108400704 times.
✓ Branch 1 taken 50521503 times.
158922207 for (tables = *start; tables; tables = tables->next_global) {
6088 108400704 TABLE *tbl = tables->table;
6089
6090 /*
6091 NOTE: temporary merge tables should be processed here too, because
6092 a temporary merge table can be based on non-temporary tables.
6093 */
6094
6095 /* Schema tables may not have a TABLE object here. */
6096
6/6
✓ Branch 0 taken 106920117 times.
✓ Branch 1 taken 1480587 times.
✓ Branch 2 taken 106916572 times.
✓ Branch 3 taken 3545 times.
✓ Branch 4 taken 4047 times.
✓ Branch 5 taken 106912525 times.
108400704 if (tbl && tbl->file && tbl->file->ht->db_type == DB_TYPE_MRG_MYISAM) {
6097 /* MERGE tables need to access parent and child TABLE_LISTs. */
6098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4047 times.
4047 assert(tbl->pos_in_table_list == tables);
6099
6/8
✓ Branch 0 taken 4047 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4047 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 4045 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 4045 times.
4047 if (tbl->db_stat && tbl->file->ha_extra(HA_EXTRA_ATTACH_CHILDREN)) {
6100 2 error = true;
6101 8 goto err;
6102 }
6103 }
6104
6105 #ifdef WITH_WSREP
6106 319298564 bool is_dml_stmt = (thd->lex->sql_command == SQLCOM_INSERT ||
6107
2/2
✓ Branch 0 taken 102406411 times.
✓ Branch 1 taken 90749 times.
102497160 thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
6108
2/2
✓ Branch 0 taken 100447232 times.
✓ Branch 1 taken 1959179 times.
102406411 thd->lex->sql_command == SQLCOM_REPLACE ||
6109
2/2
✓ Branch 0 taken 100445730 times.
✓ Branch 1 taken 1502 times.
100447232 thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
6110
2/2
✓ Branch 0 taken 100264173 times.
✓ Branch 1 taken 181557 times.
100445730 thd->lex->sql_command == SQLCOM_UPDATE ||
6111
2/2
✓ Branch 0 taken 100143655 times.
✓ Branch 1 taken 120518 times.
100264173 thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
6112
4/4
✓ Branch 0 taken 102497160 times.
✓ Branch 1 taken 5903542 times.
✓ Branch 2 taken 100102830 times.
✓ Branch 3 taken 40825 times.
311000692 thd->lex->sql_command == SQLCOM_LOAD ||
6113
2/2
✓ Branch 0 taken 131929 times.
✓ Branch 1 taken 99970901 times.
100102830 thd->lex->sql_command == SQLCOM_DELETE);
6114
6115 108400702 bool is_system_db =
6116
4/4
✓ Branch 0 taken 106920256 times.
✓ Branch 1 taken 1480446 times.
✓ Branch 2 taken 6765372 times.
✓ Branch 3 taken 100154884 times.
115166074 (tbl && ((strcmp(tbl->s->db.str, "mysql") == 0) ||
6117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6765506 times.
6765372 (strcmp(tbl->s->db.str, "information_schema") == 0)));
6118
6119 /* Schema tables may not have a TABLE object here. */
6120 108400702 legacy_db_type db_type = DB_TYPE_UNKNOWN;
6121
4/4
✓ Branch 0 taken 106920386 times.
✓ Branch 1 taken 1480316 times.
✓ Branch 2 taken 106917135 times.
✓ Branch 3 taken 3251 times.
108400702 if (tbl && tbl->file) {
6122 106917135 db_type = tbl->file->ht->db_type;
6123 }
6124
6125
4/4
✓ Branch 0 taken 2457968 times.
✓ Branch 1 taken 30874252 times.
✓ Branch 2 taken 1128323 times.
✓ Branch 3 taken 1329645 times.
33332220 if (tables == *start && db_type != DB_TYPE_INNODB &&
6126
4/4
✓ Branch 0 taken 671392 times.
✓ Branch 1 taken 456931 times.
✓ Branch 2 taken 390883 times.
✓ Branch 3 taken 280509 times.
1128323 db_type != DB_TYPE_UNKNOWN && db_type != DB_TYPE_PERFORMANCE_SCHEMA &&
6127
8/8
✓ Branch 0 taken 33332220 times.
✓ Branch 1 taken 75068482 times.
✓ Branch 2 taken 389779 times.
✓ Branch 3 taken 1104 times.
✓ Branch 4 taken 382613 times.
✓ Branch 5 taken 7167 times.
✓ Branch 6 taken 382612 times.
✓ Branch 7 taken 108018091 times.
141732922 is_dml_stmt && !is_system_db && !is_temporary_table(tables)) {
6128 /* Table is not an InnoDB table and workload is trying to make changes
6129 to the table. Validate workload based on pxc-strict-mode. */
6130
6131 382612 bool block = false;
6132
6133
3/3
✓ Branch 0 taken 382561 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 45 times.
382612 switch (pxc_strict_mode) {
6134 382561 case PXC_STRICT_MODE_DISABLED:
6135 382561 break;
6136 6 case PXC_STRICT_MODE_PERMISSIVE:
6137
10/22
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 6 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 6 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 6 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 6 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 6 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
6 WSREP_WARN(
6138 "Percona-XtraDB-Cluster doesn't recommend use of"
6139 " DML command on a table (%s.%s) that resides in"
6140 " non-transactional storage engine"
6141 " with pxc_strict_mode = PERMISSIVE",
6142 tbl->s->db.str, tbl->s->table_name.str);
6143 6 push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR,
6144 "Percona-XtraDB-Cluster doesn't recommend use of"
6145 " DML command on a table (%s.%s) that resides in"
6146 " non-transactional storage engine"
6147 " with pxc_strict_mode = PERMISSIVE",
6148
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 tbl->s->db.str, tbl->s->table_name.str);
6149 6 break;
6150 45 case PXC_STRICT_MODE_ENFORCING:
6151 case PXC_STRICT_MODE_MASTER:
6152 default:
6153 45 block = true;
6154
13/28
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
45 WSREP_ERROR(
6155 "Percona-XtraDB-Cluster prohibits use of"
6156 " DML command on a table (%s.%s) that resides in"
6157 " non-transactional storage engine"
6158 " with pxc_strict_mode = ENFORCING or MASTER",
6159 tbl->s->db.str, tbl->s->table_name.str);
6160 char message[1024];
6161 2 sprintf(message,
6162 "Percona-XtraDB-Cluster prohibits use of"
6163 " DML command on a table (%s.%s) that resides in"
6164 " non-transactional storage engine"
6165 " with pxc_strict_mode = ENFORCING or MASTER",
6166 2 tbl->s->db.str, tbl->s->table_name.str);
6167
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_message(ER_UNKNOWN_ERROR, message, MYF(0));
6168 2 break;
6169 }
6170
6171
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 382567 times.
382569 if (block) {
6172 2 error = true;
6173 2 goto err;
6174 }
6175 }
6176
6177
4/4
✓ Branch 0 taken 8276683 times.
✓ Branch 1 taken 25054976 times.
✓ Branch 2 taken 8274859 times.
✓ Branch 3 taken 1824 times.
33331659 if (tables == *start && is_dml_stmt &&
6178
2/2
✓ Branch 0 taken 8270128 times.
✓ Branch 1 taken 4731 times.
8274859 db_type != DB_TYPE_PERFORMANCE_SCHEMA && tbl &&
6179
8/8
✓ Branch 0 taken 33331659 times.
✓ Branch 1 taken 75068999 times.
✓ Branch 2 taken 2374353 times.
✓ Branch 3 taken 5895775 times.
✓ Branch 4 taken 2374080 times.
✓ Branch 5 taken 273 times.
✓ Branch 6 taken 2304499 times.
✓ Branch 7 taken 106096148 times.
144106386 tbl->s->primary_key == MAX_KEY && !is_system_db &&
6180
2/2
✓ Branch 0 taken 2304489 times.
✓ Branch 1 taken 69580 times.
2374080 !is_temporary_table(tables)) {
6181 /* Table doesn't have explicit primary-key defined. */
6182
6183 2304499 bool block = false;
6184
6185
3/3
✓ Branch 0 taken 2304155 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 342 times.
2304499 switch (pxc_strict_mode) {
6186 2304155 case PXC_STRICT_MODE_DISABLED:
6187 2304155 break;
6188 2 case PXC_STRICT_MODE_PERMISSIVE:
6189
10/22
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✓ Branch 19 taken 2 times.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 WSREP_WARN(
6190 "Percona-XtraDB-Cluster doesn't recommend use of"
6191 " DML command on a table (%s.%s) without"
6192 " an explicit primary key"
6193 " with pxc_strict_mode = PERMISSIVE",
6194 tbl->s->db.str, tbl->s->table_name.str);
6195 2 push_warning_printf(thd, Sql_condition::SL_WARNING, ER_UNKNOWN_ERROR,
6196 "Percona-XtraDB-Cluster doesn't recommend use of"
6197 " DML command on a table (%s.%s) without"
6198 " an explicit primary key"
6199 " with pxc_strict_mode = PERMISSIVE",
6200
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 tbl->s->db.str, tbl->s->table_name.str);
6201 2 break;
6202 342 case PXC_STRICT_MODE_ENFORCING:
6203 case PXC_STRICT_MODE_MASTER:
6204 default:
6205 342 block = true;
6206
13/28
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 2 times.
✗ Branch 17 not taken.
✓ Branch 18 taken 2 times.
✗ Branch 19 not taken.
✓ Branch 20 taken 2 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 2 times.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✓ Branch 25 taken 2 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
342 WSREP_ERROR(
6207 "Percona-XtraDB-Cluster prohibits use of"
6208 " DML command on a table (%s.%s) without"
6209 " an explicit primary key"
6210 " with pxc_strict_mode = ENFORCING or MASTER",
6211 tbl->s->db.str, tbl->s->table_name.str);
6212 char message[1024];
6213 2 sprintf(message,
6214 "Percona-XtraDB-Cluster prohibits use of"
6215 " DML command on a table (%s.%s) without"
6216 " an explicit primary key"
6217 " with pxc_strict_mode = ENFORCING or MASTER",
6218 2 tbl->s->db.str, tbl->s->table_name.str);
6219
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_message(ER_UNKNOWN_ERROR, message, MYF(0));
6220 2 break;
6221 }
6222
6223
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2304157 times.
2304159 if (block) {
6224 2 error = true;
6225 2 goto err;
6226 }
6227 }
6228
6229 /* It is not recommended to replicate MyISAM as it lacks rollback feature
6230 but if user demands then actions are replicated using TOI.
6231 Following code will kick-start the TOI but this has to be done only once
6232 per statement.
6233 Note: kick-start will take-care of creating isolation key for all tables
6234 involved in the list (provided all of them are MYISAM tables). */
6235
4/4
✓ Branch 0 taken 83 times.
✓ Branch 1 taken 8429477 times.
✓ Branch 2 taken 42 times.
✓ Branch 3 taken 41 times.
8429560 if (is_dml_stmt && thd->variables.wsrep_replicate_myisam &&
6236
7/8
✓ Branch 0 taken 8429560 times.
✓ Branch 1 taken 99970745 times.
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 39 times.
✓ Branch 7 taken 108400266 times.
116829865 db_type == DB_TYPE_MYISAM && wsrep_thd_is_local(thd)) {
6237
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 wsrep_before_rollback(thd, true);
6238
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 wsrep_after_rollback(thd, true);
6239
1/2
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
39 wsrep_after_statement(thd);
6240
8/14
✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 39 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 38 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 38 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 38 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 39 times.
39 if (WSREP(thd) && wsrep_to_isolation_begin(thd, NULL, NULL, (*start))) {
6241 error = true;
6242 goto err;
6243 }
6244 }
6245 #endif /* WITH_WSREP */
6246
6247 /*
6248 Access to ACL table in a SELECT ... LOCK IN SHARE MODE are required
6249 to skip acquiring row locks. So, we use TL_READ_DEFAULT lock on ACL
6250 tables. This allows concurrent ACL DDL's.
6251
6252 Do not request SE to skip row lock if 'flags' has
6253 MYSQL_OPEN_FORCE_SHARED_MDL, which indicates that this is PREPARE
6254 phase. It is OK to do so since during this phase no rows will be read
6255 anyway. And by doing this we avoid generation of extra warnings.
6256 EXECUTION phase will request SE to skip row locks if necessary.
6257 */
6258 108400305 bool issue_warning_on_skipping_row_lock = false;
6259 108400305 if (tables->lock_descriptor().type == TL_READ_WITH_SHARED_LOCKS &&
6260
6/6
✓ Branch 0 taken 637 times.
✓ Branch 1 taken 108399592 times.
✓ Branch 2 taken 636 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 41 times.
✓ Branch 5 taken 108400188 times.
108400865 !(flags & MYSQL_OPEN_FORCE_SHARED_MDL) &&
6261
3/4
✓ Branch 0 taken 636 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41 times.
✓ Branch 3 taken 595 times.
636 is_acl_table_in_non_LTM(tables, thd->locked_tables_mode)) {
6262 41 tables->set_lock({TL_READ_DEFAULT, THR_DEFAULT});
6263 41 issue_warning_on_skipping_row_lock = true;
6264 }
6265
6266 /* Set appropriate TABLE::lock_type. */
6267
6/6
✓ Branch 0 taken 106919760 times.
✓ Branch 1 taken 1480469 times.
✓ Branch 2 taken 106879113 times.
✓ Branch 3 taken 41156 times.
✓ Branch 4 taken 106748062 times.
✓ Branch 5 taken 1652676 times.
215279342 if (tbl && tables->lock_descriptor().type != TL_UNLOCK &&
6268
2/2
✓ Branch 0 taken 106747936 times.
✓ Branch 1 taken 131177 times.
106879113 !thd->locked_tables_mode) {
6269
2/2
✓ Branch 0 taken 2475343 times.
✓ Branch 1 taken 104272782 times.
106748062 if (tables->lock_descriptor().type == TL_WRITE_DEFAULT)
6270 2475343 tbl->reginfo.lock_type = thd->update_lock_default;
6271
2/2
✓ Branch 0 taken 5847641 times.
✓ Branch 1 taken 98425108 times.
104272782 else if (tables->lock_descriptor().type == TL_WRITE_CONCURRENT_DEFAULT)
6272 5847641 tables->table->reginfo.lock_type = thd->insert_lock_default;
6273
2/2
✓ Branch 0 taken 4013380 times.
✓ Branch 1 taken 94411765 times.
98425108 else if (tables->lock_descriptor().type == TL_READ_DEFAULT)
6274
1/2
✓ Branch 0 taken 4013377 times.
✗ Branch 1 not taken.
4013380 tbl->reginfo.lock_type = read_lock_type_for_table(
6275
1/2
✓ Branch 0 taken 4013380 times.
✗ Branch 1 not taken.
4013380 thd, thd->lex, tables, some_routine_modifies_data);
6276 else
6277 94411765 tbl->reginfo.lock_type = tables->lock_descriptor().type;
6278 }
6279
6280 /*
6281 SELECT using a I_S system view with 'FOR UPDATE' and
6282 'LOCK IN SHARED MODE' clause is not allowed.
6283 */
6284
4/4
✓ Branch 0 taken 443795 times.
✓ Branch 1 taken 107957002 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 108400796 times.
108844593 if (tables->is_system_view &&
6285
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 443794 times.
443795 tables->lock_descriptor().type == TL_READ_WITH_SHARED_LOCKS) {
6286
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 my_error(ER_IS_QUERY_INVALID_CLAUSE, MYF(0), "LOCK IN SHARE MODE");
6287 2 error = true;
6288 2 goto err;
6289 }
6290
6291 // Setup lock type for DD tables used under I_S view.
6292
2/4
✓ Branch 0 taken 108400090 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 108400090 times.
108400796 if (set_non_locking_read_for_IS_view(thd, tables)) {
6293 error = true;
6294 goto err;
6295 }
6296
6297 /**
6298 Setup lock type for read requests for ACL table in SQL statements.
6299
6300 Do not request SE to skip row lock if 'flags' has
6301 MYSQL_OPEN_FORCE_SHARED_MDL, which indicates that this is PREPARE
6302 phase. It is OK to do so since during this phase no rows will be read
6303 anyway. And by doing this we avoid generation of extra warnings.
6304 EXECUTION phase will request SE to skip row locks if necessary.
6305 */
6306
3/4
✓ Branch 0 taken 108342395 times.
✓ Branch 1 taken 57695 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 108400535 times.
216742930 if (!(flags & MYSQL_OPEN_FORCE_SHARED_MDL) &&
6307
2/4
✓ Branch 0 taken 108342840 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 108342840 times.
108342395 set_non_locking_read_for_ACL_table(
6308 thd, tables, issue_warning_on_skipping_row_lock)) {
6309 error = true;
6310 goto err;
6311 }
6312
6313 } // End of for(;;)
6314
6315 50521503 err:
6316 // If a new TABLE was introduced, it's garbage, don't link to it:
6317
6/6
✓ Branch 0 taken 63898 times.
✓ Branch 1 taken 50521507 times.
✓ Branch 2 taken 63742 times.
✓ Branch 3 taken 156 times.
✓ Branch 4 taken 35243 times.
✓ Branch 5 taken 28499 times.
50585405 if (error && *table_to_open && old_table != (*table_to_open)->table) {
6318 35243 (*table_to_open)->table = nullptr;
6319 }
6320
5/8
✓ Branch 0 taken 50585108 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50585600 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1458 times.
✓ Branch 5 taken 50584142 times.
✓ Branch 6 taken 1305 times.
✗ Branch 7 not taken.
50585405 DBUG_PRINT("open_tables", ("returning: %d", (int)error));
6321 50585447 return error;
6322 50585463 }
6323
6324 /**
6325 Defines how prelocking algorithm for DML statements should handle routines:
6326 - For CALL statements we do unrolling (i.e. open and lock tables for each
6327 sub-statement individually). So for such statements prelocking is enabled
6328 only if stored functions are used in parameter list and only for period
6329 during which we calculate values of parameters. Thus in this strategy we
6330 ignore procedure which is directly called by such statement and extend
6331 the prelocking set only with tables/functions used by SF called from the
6332 parameter list.
6333 - For any other statement any routine which is directly or indirectly called
6334 by statement is going to be executed in prelocked mode. So in this case we
6335 simply add all tables and routines used by it to the prelocking set.
6336
6337 @param[in] thd Thread context.
6338 @param[in] prelocking_ctx Prelocking context of the statement.
6339 @param[in] rt Prelocking set element describing routine.
6340 @param[in] sp Routine body.
6341 @param[out] need_prelocking Set to true if method detects that prelocking
6342 required, not changed otherwise.
6343
6344 @retval false Success.
6345 @retval true Failure (OOM).
6346 */
6347
6348 115361 bool DML_prelocking_strategy::handle_routine(THD *thd,
6349 Query_tables_list *prelocking_ctx,
6350 Sroutine_hash_entry *rt,
6351 sp_head *sp,
6352 bool *need_prelocking) {
6353 /*
6354 We assume that for any "CALL proc(...)" statement sroutines_list will
6355 have 'proc' as first element (it may have several, consider e.g.
6356 "proc(sp_func(...)))". This property is currently guaranteed by the
6357 parser.
6358 */
6359
6360
4/6
✓ Branch 0 taken 51246 times.
✓ Branch 1 taken 64115 times.
✓ Branch 2 taken 51246 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 115361 times.
✗ Branch 5 not taken.
166607 if (rt != prelocking_ctx->sroutines_list.first ||
6361 51246 rt->type() != Sroutine_hash_entry::PROCEDURE) {
6362 115361 *need_prelocking = true;
6363 115361 sp_update_stmt_used_routines(thd, prelocking_ctx, &sp->m_sroutines,
6364 rt->belong_to_view);
6365 115361 sp->add_used_tables_to_table_list(thd, &prelocking_ctx->query_tables_last,
6366 prelocking_ctx->sql_command,
6367 rt->belong_to_view);
6368 }
6369 115361 sp->propagate_attributes(prelocking_ctx);
6370 115361 return false;
6371 }
6372
6373 /**
6374 Defines how prelocking algorithm for DML statements should handle table list
6375 elements:
6376 - If table has triggers we should add all tables and routines
6377 used by them to the prelocking set.
6378 - If table participates in a foreign key we should add another
6379 table from it to the prelocking set with an appropriate metadata
6380 lock.
6381
6382 We do not need to acquire metadata locks on trigger names
6383 in DML statements, since all DDL statements
6384 that change trigger metadata always lock their
6385 subject tables.
6386
6387 @param[in] thd Thread context.
6388 @param[in] prelocking_ctx Prelocking context of the statement.
6389 @param[in] table_list Table list element for table.
6390 @param[out] need_prelocking Set to true if method detects that prelocking
6391 required, not changed otherwise.
6392
6393 @retval false Success.
6394 @retval true Failure (OOM).
6395 */
6396
6397 26634484 bool DML_prelocking_strategy::handle_table(THD *thd,
6398 Query_tables_list *prelocking_ctx,
6399 TABLE_LIST *table_list,
6400 bool *need_prelocking) {
6401 /* We rely on a caller to check that table is going to be changed. */
6402
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26635509 times.
26634484 assert(table_list->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE);
6403
6404
2/2
✓ Branch 0 taken 8336424 times.
✓ Branch 1 taken 18299085 times.
26635509 if (table_list->trg_event_map) {
6405
2/2
✓ Branch 0 taken 45823 times.
✓ Branch 1 taken 8290601 times.
8336424 if (table_list->table->triggers) {
6406 45823 *need_prelocking = true;
6407
6408
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45822 times.
45823 if (table_list->table->triggers->add_tables_and_routines_for_triggers(
6409 thd, prelocking_ctx, table_list))
6410 return true;
6411 }
6412
6413 /*
6414 When FOREIGN_KEY_CHECKS is 0 we are not going to do any foreign key checks
6415 so we don't need to add child and parent tables to the prelocking list.
6416
6417 However, since trigger or stored function might change this variable for
6418 their duration (it is, actually, advisable to do so in some scenarios),
6419 we can apply this optimization only to tables which are directly used by
6420 the top-level statement.
6421
6422 While processing LOCK TABLES, we must disregard F_K_C too, since the
6423 prelocking set will be used while in LTM mode, and F_K_C may be turned
6424 on later, after the set has been established.
6425 */
6426
2/2
✓ Branch 0 taken 7538 times.
✓ Branch 1 taken 8328885 times.
8336423 if ((!(thd->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS) ||
6427
2/2
✓ Branch 0 taken 6952 times.
✓ Branch 1 taken 586 times.
7538 prelocking_ctx->sql_command == SQLCOM_LOCK_TABLES ||
6428
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 6923 times.
6952 table_list->prelocking_placeholder) &&
6429
2/2
✓ Branch 0 taken 8130739 times.
✓ Branch 1 taken 198761 times.
8329500 !(table_list->table->s->tmp_table)) {
6430 8130739 bool is_insert =
6431 8130739 (table_list->trg_event_map &
6432 static_cast<uint8>(1 << static_cast<int>(TRG_EVENT_INSERT)));
6433 8130739 bool is_update =
6434 8130739 (table_list->trg_event_map &
6435 static_cast<uint8>(1 << static_cast<int>(TRG_EVENT_UPDATE)));
6436 8130739 bool is_delete =
6437 8130739 (table_list->trg_event_map &
6438 static_cast<uint8>(1 << static_cast<int>(TRG_EVENT_DELETE)));
6439
6440 8130739 process_table_fks(thd, prelocking_ctx, table_list->table->s, is_insert,
6441 is_update, is_delete, table_list->belong_to_view,
6442 need_prelocking);
6443 }
6444 }
6445 26634897 return false;
6446 }
6447
6448 /**
6449 Defines how prelocking algorithm for DML statements should handle view -
6450 all view routines should be added to the prelocking set.
6451
6452 @param[in] thd Thread context.
6453 @param[in] prelocking_ctx Prelocking context of the statement.
6454 @param[in] table_list Table list element for view.
6455 @param[out] need_prelocking Set to true if method detects that prelocking
6456 required, not changed otherwise.
6457
6458 @retval false Success.
6459 @retval true Failure (OOM).
6460 */
6461
6462 575843 bool DML_prelocking_strategy::handle_view(THD *thd,
6463 Query_tables_list *prelocking_ctx,
6464 TABLE_LIST *table_list,
6465 bool *need_prelocking) {
6466
2/2
✓ Branch 0 taken 33811 times.
✓ Branch 1 taken 542034 times.
575843 if (table_list->view_query()->uses_stored_routines()) {
6467 33811 *need_prelocking = true;
6468
6469 67622 sp_update_stmt_used_routines(thd, prelocking_ctx,
6470 33811 &table_list->view_query()->sroutines_list,
6471 table_list->top_table());
6472 }
6473
6474 /*
6475 If a trigger was defined on one of the associated tables then assign the
6476 'trg_event_map' value of the view to the next table in table_list. When a
6477 Stored function is invoked, all the associated tables including the tables
6478 associated with the trigger are prelocked.
6479 */
6480
4/4
✓ Branch 0 taken 11471 times.
✓ Branch 1 taken 564374 times.
✓ Branch 2 taken 11448 times.
✓ Branch 3 taken 23 times.
575845 if (table_list->trg_event_map && table_list->next_global)
6481 11448 table_list->next_global->trg_event_map = table_list->trg_event_map;
6482 575845 return false;
6483 }
6484
6485 /**
6486 Defines how prelocking algorithm for LOCK TABLES statement should handle
6487 table list elements.
6488
6489 @param[in] thd Thread context.
6490 @param[in] prelocking_ctx Prelocking context of the statement.
6491 @param[in] table_list Table list element for table.
6492 @param[out] need_prelocking Set to true if method detects that prelocking
6493 required, not changed otherwise.
6494
6495 @retval false Success.
6496 @retval true Failure (OOM).
6497 */
6498
6499 1618 bool Lock_tables_prelocking_strategy::handle_table(
6500 THD *thd, Query_tables_list *prelocking_ctx, TABLE_LIST *table_list,
6501 bool *need_prelocking) {
6502
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1618 times.
1618 if (DML_prelocking_strategy::handle_table(thd, prelocking_ctx, table_list,
6503 need_prelocking))
6504 return true;
6505
6506 /* We rely on a caller to check that table is going to be changed. */
6507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1618 times.
1618 assert(table_list->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE);
6508
6509 1618 return false;
6510 }
6511
6512 /**
6513 Defines how prelocking algorithm for ALTER TABLE statement should handle
6514 routines - do nothing as this statement is not supposed to call routines.
6515
6516 We still can end up in this method when someone tries
6517 to define a foreign key referencing a view, and not just
6518 a simple view, but one that uses stored routines.
6519 */
6520
6521 1 bool Alter_table_prelocking_strategy::handle_routine(THD *, Query_tables_list *,
6522 Sroutine_hash_entry *,
6523 sp_head *, bool *) {
6524 1 return false;
6525 }
6526
6527 /**
6528 Defines how prelocking algorithm for ALTER TABLE statement should handle
6529 table list elements.
6530
6531 Unlike in DML, we do not process triggers here.
6532 */
6533
6534 941 bool Alter_table_prelocking_strategy::handle_table(THD *, Query_tables_list *,
6535 TABLE_LIST *, bool *) {
6536 941 return false;
6537 }
6538
6539 /**
6540 Defines how prelocking algorithm for ALTER TABLE statement
6541 should handle view - do nothing. We don't need to add view
6542 routines to the prelocking set in this case as view is not going
6543 to be materialized.
6544 */
6545
6546 1 bool Alter_table_prelocking_strategy::handle_view(THD *, Query_tables_list *,
6547 TABLE_LIST *, bool *) {
6548 1 return false;
6549 }
6550
6551 /**
6552 Check that lock is ok for tables; Call start stmt if ok
6553
6554 @param thd Thread handle.
6555 @param prelocking_ctx Prelocking context.
6556 @param table_list Table list element for table to be checked.
6557
6558 @retval false - Ok.
6559 @retval true - Error.
6560 */
6561
6562 2172842 static bool check_lock_and_start_stmt(THD *thd,
6563 Query_tables_list *prelocking_ctx,
6564 TABLE_LIST *table_list) {
6565 int error;
6566 thr_lock_type lock_type;
6567
1/2
✓ Branch 0 taken 2172842 times.
✗ Branch 1 not taken.
2172842 DBUG_TRACE;
6568
6569 /*
6570 Prelocking placeholder is not set for TABLE_LIST that
6571 are directly used by TOP level statement.
6572 */
6573
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2172842 times.
2172842 assert(table_list->prelocking_placeholder == false);
6574
6575 /*
6576 TL_WRITE_DEFAULT, TL_READ_DEFAULT and TL_WRITE_CONCURRENT_DEFAULT
6577 are supposed to be parser only types of locks so they should be
6578 converted to appropriate other types to be passed to storage engine.
6579 The exact lock type passed to the engine is important as, for example,
6580 InnoDB uses it to determine what kind of row locks should be acquired
6581 when executing statement in prelocked mode or under LOCK TABLES with
6582 @@innodb_table_locks = 0.
6583
6584 Last argument routine_modifies_data for read_lock_type_for_table()
6585 is ignored, as prelocking placeholder will never be set here.
6586 */
6587
2/2
✓ Branch 0 taken 2006710 times.
✓ Branch 1 taken 166132 times.
2172842 if (table_list->lock_descriptor().type == TL_WRITE_DEFAULT)
6588 2006710 lock_type = thd->update_lock_default;
6589
2/2
✓ Branch 0 taken 46863 times.
✓ Branch 1 taken 119269 times.
166132 else if (table_list->lock_descriptor().type == TL_WRITE_CONCURRENT_DEFAULT)
6590 46863 lock_type = thd->insert_lock_default;
6591
2/2
✓ Branch 0 taken 92684 times.
✓ Branch 1 taken 26585 times.
119269 else if (table_list->lock_descriptor().type == TL_READ_DEFAULT)
6592
1/2
✓ Branch 0 taken 92684 times.
✗ Branch 1 not taken.
92684 lock_type = read_lock_type_for_table(thd, prelocking_ctx, table_list, true);
6593 else
6594 26585 lock_type = table_list->lock_descriptor().type;
6595
6596
2/2
✓ Branch 0 taken 2053617 times.
✓ Branch 1 taken 119225 times.
2172842 if ((int)lock_type > (int)TL_WRITE_ALLOW_WRITE &&
6597
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 2053600 times.
2053617 (int)table_list->table->reginfo.lock_type <= (int)TL_WRITE_ALLOW_WRITE) {
6598
1/2
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
17 my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), table_list->alias);
6599 17 return true;
6600 }
6601
2/4
✓ Branch 0 taken 2172825 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2172825 times.
2172825 if ((error = table_list->table->file->start_stmt(thd, lock_type))) {
6602 table_list->table->file->print_error(error, MYF(0));
6603 return true;
6604 }
6605
6606 /*
6607 Record in transaction state tracking
6608 */
6609
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2172822 times.
2172825 if (thd->variables.session_track_transaction_info > TX_TRACK_NONE) {
6610
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 TX_TRACKER_GET(tst);
6611 enum enum_tx_state s;
6612
6613
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 s = tst->calc_trx_state(lock_type,
6614 3 table_list->table->file->has_transactions());
6615
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 tst->add_trx_state(thd, s);
6616 }
6617
6618 2172825 return false;
6619 2172842 }
6620
6621 /**
6622 @brief Open and lock one table
6623
6624 @param[in] thd thread handle
6625 @param[in] table_l table to open is first table in this list
6626 @param[in] lock_type lock to use for table
6627 @param[in] flags options to be used while opening and locking
6628 table (see open_table(), mysql_lock_tables())
6629 @param[in] prelocking_strategy Strategy which specifies how prelocking
6630 algorithm should work for this statement.
6631
6632 @return table
6633 @retval != NULL OK, opened table returned
6634 @retval NULL Error
6635
6636 @note
6637 If ok, the following are also set:
6638 table_list->lock_type lock_type
6639 table_list->table table
6640
6641 @note
6642 If table_l is a list, not a single table, the list is temporarily
6643 broken.
6644
6645 @details
6646 This function is meant as a replacement for open_ltable() when
6647 MERGE tables can be opened. open_ltable() cannot open MERGE tables.
6648
6649 There may be more differences between open_n_lock_single_table() and
6650 open_ltable(). One known difference is that open_ltable() does
6651 neither call thd->decide_logging_format() nor handle some other logging
6652 and locking issues because it does not call lock_tables().
6653 */
6654
6655 1272199 TABLE *open_n_lock_single_table(THD *thd, TABLE_LIST *table_l,
6656 thr_lock_type lock_type, uint flags,
6657 Prelocking_strategy *prelocking_strategy) {
6658 TABLE_LIST *save_next_global;
6659
1/2
✓ Branch 0 taken 1272405 times.
✗ Branch 1 not taken.
1272199 DBUG_TRACE;
6660
6661 /* Remember old 'next' pointer. */
6662 1272405 save_next_global = table_l->next_global;
6663 /* Break list. */
6664 1272405 table_l->next_global = nullptr;
6665
6666 /* Set requested lock type. */
6667 1272405 table_l->set_lock({lock_type, THR_DEFAULT});
6668 /* Allow to open real tables only. */
6669 1272281 table_l->required_type = dd::enum_table_type::BASE_TABLE;
6670
6671 /* Open the table. */
6672
3/4
✓ Branch 0 taken 1272018 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 1271985 times.
1272281 if (open_and_lock_tables(thd, table_l, flags, prelocking_strategy))
6673 33 table_l->table = nullptr; /* Just to be sure. */
6674
6675 /* Restore list. */
6676 1272018 table_l->next_global = save_next_global;
6677
6678 1272403 return table_l->table;
6679 1272018 }
6680
6681 /*
6682 Open and lock one table
6683
6684 SYNOPSIS
6685 open_ltable()
6686 thd Thread handler
6687 table_list Table to open is first table in this list
6688 lock_type Lock to use for open
6689 lock_flags Flags passed to mysql_lock_table
6690
6691 NOTE
6692 This function doesn't do anything like SP/SF/views/triggers analysis done
6693 in open_table()/lock_tables(). It is intended for opening of only one
6694 concrete table. And used only in special contexts.
6695
6696 RETURN VALUES
6697 table Opened table
6698 0 Error
6699
6700 If ok, the following are also set:
6701 table_list->lock_type lock_type
6702 table_list->table table
6703 */
6704
6705 109650 TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
6706 uint lock_flags) {
6707 TABLE *table;
6708
1/2
✓ Branch 0 taken 109649 times.
✗ Branch 1 not taken.
109650 Open_table_context ot_ctx(thd, lock_flags);
6709 bool error;
6710
1/2
✓ Branch 0 taken 109643 times.
✗ Branch 1 not taken.
109649 DBUG_TRACE;
6711
6712 /* should not be used in a prelocked_mode context, see NOTE above */
6713
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109643 times.
109643 assert(thd->locked_tables_mode < LTM_PRELOCKED);
6714
6715
2/2
✓ Branch 0 taken 71752 times.
✓ Branch 1 taken 37891 times.
109643 if (!(thd->state_flags & Open_tables_state::SYSTEM_TABLES))
6716
1/2
✓ Branch 0 taken 71757 times.
✗ Branch 1 not taken.
71752 THD_STAGE_INFO(thd, stage_opening_tables);
6717
6718 /* open_ltable can be used only for BASIC TABLEs */
6719 109648 table_list->required_type = dd::enum_table_type::BASE_TABLE;
6720
6721 /* This function can't properly handle requests for such metadata locks. */
6722
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109646 times.
109648 assert(!table_list->mdl_request.is_ddl_or_lock_tables_lock_request());
6723
6724
5/8
✓ Branch 0 taken 109636 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 109631 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 109636 times.
109651 while ((error = open_table(thd, table_list, &ot_ctx)) &&
6725 5 ot_ctx.can_recover_from_failed_open()) {
6726 /*
6727 Even though we have failed to open table we still need to
6728 call release_transactional_locks() to release metadata locks which
6729 might have been acquired successfully.
6730 */
6731 thd->mdl_context.rollback_to_savepoint(ot_ctx.start_of_statement_svp());
6732 table_list->mdl_request.ticket = nullptr;
6733 if (ot_ctx.recover_from_failed_open()) break;
6734 }
6735
6736
2/2
✓ Branch 0 taken 109587 times.
✓ Branch 1 taken 49 times.
109636 if (!error) {
6737 /*
6738 We can't have a view or some special "open_strategy" in this function
6739 so there should be a TABLE instance.
6740 */
6741
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109587 times.
109587 assert(table_list->table);
6742 109587 table = table_list->table;
6743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109587 times.
109587 if (table->file->ht->db_type == DB_TYPE_MRG_MYISAM) {
6744 /* A MERGE table must not come here. */
6745 /* purecov: begin tested */
6746 my_error(ER_WRONG_OBJECT, MYF(0), table->s->db.str,
6747 table->s->table_name.str, "BASE TABLE");
6748 table = nullptr;
6749 goto end;
6750 /* purecov: end */
6751 }
6752
6753 109587 table_list->set_lock({lock_type, THR_DEFAULT});
6754
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109581 times.
109581 if (thd->locked_tables_mode) {
6755 if (check_lock_and_start_stmt(thd, thd->lex, table_list)) table = nullptr;
6756 } else {
6757
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 109581 times.
109581 assert(thd->lock == nullptr); // You must lock everything at once
6758
1/2
✓ Branch 0 taken 109612 times.
✗ Branch 1 not taken.
109581 if ((table->reginfo.lock_type = lock_type) != TL_UNLOCK)
6759 109603 if (!(thd->lock =
6760
3/4
✓ Branch 0 taken 109603 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 109602 times.
109612 mysql_lock_tables(thd, &table_list->table, 1, lock_flags))) {
6761 1 table = nullptr;
6762 }
6763 }
6764 } else
6765 49 table = nullptr;
6766
6767 109621 end:
6768
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 109615 times.
109621 if (table == nullptr) {
6769
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 if (!thd->in_sub_stmt) trans_rollback_stmt(thd);
6770
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 close_thread_tables(thd);
6771 }
6772 109601 return table;
6773 109621 }
6774
6775 /**
6776 Open all tables in list, locks them and optionally process derived tables.
6777
6778 @param thd Thread context.
6779 @param tables List of tables for open and locking.
6780 @param flags Bitmap of options to be used to open and lock
6781 tables (see open_tables() and mysql_lock_tables()
6782 for details).
6783 @param prelocking_strategy Strategy which specifies how prelocking algorithm
6784 should work for this statement.
6785
6786 @note
6787 The thr_lock locks will automatically be freed by close_thread_tables().
6788
6789 @note
6790 open_and_lock_tables() is not intended for open-and-locking system tables
6791 in those cases when execution of statement has started already and other
6792 tables have been opened. Use open_trans_system_tables_for_read() instead.
6793
6794 @retval false OK.
6795 @retval true Error
6796 */
6797
6798 10982642 bool open_and_lock_tables(THD *thd, TABLE_LIST *tables, uint flags,
6799 Prelocking_strategy *prelocking_strategy) {
6800 uint counter;
6801
1/2
✓ Branch 0 taken 10983529 times.
✗ Branch 1 not taken.
10982642 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
6802
1/2
✓ Branch 0 taken 10983802 times.
✗ Branch 1 not taken.
10983529 DBUG_TRACE;
6803
6804 /*
6805 open_and_lock_tables() must not be used to open system tables. There must
6806 be no active attachable transaction when open_and_lock_tables() is called.
6807 Exception is made to the read-write attachables with explicitly specified
6808 in the assert table.
6809 Callers in the read-write case must make sure no side effect to
6810 the global transaction state is inflicted when the attachable one
6811 will commit.
6812 */
6813
4/10
✓ Branch 0 taken 10983754 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10983773 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10983201 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 10983201 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
10983802 assert(!thd->is_attachable_ro_transaction_active() &&
6814 (!thd->is_attachable_rw_transaction_active() ||
6815 !strcmp(tables->table_name, "gtid_executed")));
6816
6817
3/4
✓ Branch 0 taken 10983552 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2753 times.
✓ Branch 3 taken 10980799 times.
10983235 if (open_tables(thd, &tables, &counter, flags, prelocking_strategy)) goto err;
6818
6819
2/6
✓ Branch 0 taken 10980693 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 10980693 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
10980799 DBUG_EXECUTE_IF("sleep_open_and_lock_after_open", {
6820 const char *old_proc_info = thd->proc_info();
6821 thd->set_proc_info("DBUG sleep");
6822 my_sleep(6000000);
6823 thd->set_proc_info(old_proc_info);
6824 });
6825
6826
3/4
✓ Branch 0 taken 10980690 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 10980673 times.
10980693 if (lock_tables(thd, tables, counter, flags)) goto err;
6827
6828 10980673 return false;
6829 2770 err:
6830 // Rollback the statement execution done so far
6831
3/4
✓ Branch 0 taken 2752 times.
✓ Branch 1 taken 18 times.
✓ Branch 2 taken 2752 times.
✗ Branch 3 not taken.
2770 if (!thd->in_sub_stmt) trans_rollback_stmt(thd);
6832
1/2
✓ Branch 0 taken 2770 times.
✗ Branch 1 not taken.
2770 close_thread_tables(thd);
6833 /* Don't keep locks for a failed statement. */
6834
1/2
✓ Branch 0 taken 2770 times.
✗ Branch 1 not taken.
2770 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
6835 2770 return true;
6836 10983443 }
6837
6838 /**
6839 Check if a secondary engine can be used to execute the current
6840 statement, and if so, replace the opened tables with their secondary
6841 counterparts.
6842
6843 @param thd thread handler
6844 @param flags bitmap of flags to pass to open_table
6845 @return true if an error is raised, false otherwise
6846 */
6847 18644880 static bool open_secondary_engine_tables(THD *thd, uint flags) {
6848 18644880 LEX *const lex = thd->lex;
6849 18644880 Sql_cmd *const sql_cmd = lex->m_sql_cmd;
6850
6851 // The previous execution context should have been destroyed.
6852
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18645248 times.
18644880 assert(lex->secondary_engine_execution_context() == nullptr);
6853
6854 // If use of secondary engines has been disabled for the statement,
6855 // there is nothing to do.
6856
6/6
✓ Branch 0 taken 17045771 times.
✓ Branch 1 taken 1599477 times.
✓ Branch 2 taken 143057 times.
✓ Branch 3 taken 16902621 times.
✓ Branch 4 taken 1742553 times.
✓ Branch 5 taken 16902602 times.
18645248 if (sql_cmd == nullptr || sql_cmd->secondary_storage_engine_disabled())
6857 1742553 return false;
6858
6859 // If the user has requested the use of a secondary storage engine
6860 // for this statement, skip past the initial optimization for the
6861 // primary storage engine and go straight to the secondary engine.
6862 16902602 if (thd->secondary_engine_optimization() ==
6863
4/4
✓ Branch 0 taken 13054886 times.
✓ Branch 1 taken 3847878 times.
✓ Branch 2 taken 86 times.
✓ Branch 3 taken 16902678 times.
29957650 Secondary_engine_optimization::PRIMARY_TENTATIVELY &&
6864
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 13054800 times.
13054886 thd->variables.use_secondary_engine == SECONDARY_ENGINE_FORCED) {
6865 86 thd->set_secondary_engine_optimization(
6866 Secondary_engine_optimization::SECONDARY);
6867
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 mysql_thread_set_secondary_engine(true);
6868
1/2
✓ Branch 0 taken 86 times.
✗ Branch 1 not taken.
86 mysql_statement_set_secondary_engine(thd->m_statement_psi, true);
6869 }
6870
6871 // Only open secondary engine tables if use of a secondary engine
6872 // has been requested.
6873
2/2
✓ Branch 0 taken 16902546 times.
✓ Branch 1 taken 420 times.
16902764 if (thd->secondary_engine_optimization() !=
6874 Secondary_engine_optimization::SECONDARY)
6875 16902546 return false;
6876
6877 // If the statement cannot be executed in a secondary engine because
6878 // of a property of the statement, do not attempt to open the
6879 // secondary tables. Also disable use of secondary engines for
6880 // future executions of the statement, since these properties will
6881 // not change between executions.
6882 const LEX_CSTRING *secondary_engine =
6883
1/2
✓ Branch 0 taken 439 times.
✗ Branch 1 not taken.
420 sql_cmd->eligible_secondary_storage_engine();
6884 const plugin_ref secondary_engine_plugin =
6885 secondary_engine == nullptr
6886
2/2
✓ Branch 0 taken 404 times.
✓ Branch 1 taken 35 times.
439 ? nullptr
6887
1/2
✓ Branch 0 taken 404 times.
✗ Branch 1 not taken.
404 : ha_resolve_by_name(thd, secondary_engine, false);
6888
6889
4/4
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 39 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 400 times.
839 if ((secondary_engine_plugin == nullptr) ||
6890
2/4
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 400 times.
400 !plugin_is_ready(*secondary_engine, MYSQL_STORAGE_ENGINE_PLUGIN)) {
6891 // Didn't find a secondary storage engine to use for the query.
6892 39 sql_cmd->disable_secondary_storage_engine();
6893 39 return false;
6894 }
6895
6896 // If the statement cannot be executed in a secondary engine because
6897 // of a property of the environment, do not attempt to open the
6898 // secondary tables. However, do not disable use of secondary
6899 // storage engines for future executions of the statement, since the
6900 // environment may change before the next execution.
6901
3/4
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 399 times.
400 if (!thd->is_secondary_storage_engine_eligible()) return false;
6902
6903 399 auto hton = plugin_data<const handlerton *>(secondary_engine_plugin);
6904 399 sql_cmd->use_secondary_storage_engine(hton);
6905
6906 // Replace the TABLE objects in the TABLE_LIST with secondary tables.
6907
1/2
✓ Branch 0 taken 399 times.
✗ Branch 1 not taken.
399 Open_table_context ot_ctx(thd, flags | MYSQL_OPEN_SECONDARY_ENGINE);
6908 399 TABLE_LIST *tl = lex->query_tables;
6909 // For INSERT INTO SELECT and CTAS statements, the table to insert into does
6910 // not have to have a secondary engine. This table is always first in the list
6911
2/2
✓ Branch 0 taken 390 times.
✓ Branch 1 taken 9 times.
399 if ((lex->sql_command == SQLCOM_INSERT_SELECT ||
6912
3/4
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 386 times.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
399 lex->sql_command == SQLCOM_CREATE_TABLE) &&
6913 tl != nullptr)
6914 13 tl = tl->next_global;
6915
2/2
✓ Branch 0 taken 606 times.
✓ Branch 1 taken 304 times.
910 for (; tl != nullptr; tl = tl->next_global) {
6916
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 549 times.
606 if (tl->is_placeholder()) continue;
6917 549 TABLE *primary_table = tl->table;
6918 549 tl->table = nullptr;
6919
3/4
✓ Branch 0 taken 549 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 95 times.
✓ Branch 3 taken 454 times.
549 if (open_table(thd, tl, &ot_ctx)) {
6920
2/4
✓ Branch 0 taken 95 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 95 times.
95 if (!thd->is_error()) {
6921 /*
6922 open_table() has not registered any error, implying that we can
6923 retry the failed open; but it is complicated to do so reliably, so we
6924 prefer to simply fail and re-prepare the statement in the primary
6925 engine, as an exceptional case. So we register an error.
6926 */
6927 my_error(ER_SECONDARY_ENGINE_PLUGIN, MYF(0),
6928 "Transient error when opening tables in RAPID");
6929 }
6930 95 return true;
6931 }
6932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 454 times.
454 assert(tl->table->s->is_secondary_engine());
6933
1/2
✓ Branch 0 taken 454 times.
✗ Branch 1 not taken.
454 tl->table->file->ha_set_primary_handler(primary_table->file);
6934 }
6935
6936 // Prepare the secondary engine for executing the statement.
6937
1/2
✓ Branch 0 taken 304 times.
✗ Branch 1 not taken.
608 return hton->prepare_secondary_engine != nullptr &&
6938
3/4
✓ Branch 0 taken 304 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 303 times.
608 hton->prepare_secondary_engine(thd, lex);
6939 }
6940
6941 /**
6942 Open all tables for a query or statement, in list started by "tables"
6943
6944 @param thd thread handler
6945 @param tables list of tables for open
6946 @param flags bitmap of flags to modify how the tables will be open:
6947 MYSQL_LOCK_IGNORE_FLUSH - open table even if someone has
6948 done a flush on it.
6949
6950 @retval false - ok
6951 @retval true - error
6952
6953 @note
6954 This is to be used on prepare stage when you don't read any
6955 data from the tables.
6956
6957 @note
6958 Updates Query_tables_list::table_count as side-effect.
6959 */
6960
6961 18696746 bool open_tables_for_query(THD *thd, TABLE_LIST *tables, uint flags) {
6962 18696746 DML_prelocking_strategy prelocking_strategy;
6963
1/2
✓ Branch 0 taken 18697947 times.
✗ Branch 1 not taken.
18696746 MDL_savepoint mdl_savepoint = thd->mdl_context.mdl_savepoint();
6964
1/2
✓ Branch 0 taken 18698298 times.
✗ Branch 1 not taken.
18697947 DBUG_TRACE;
6965
6966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18698298 times.
18698298 assert(tables == thd->lex->query_tables);
6967
6968
3/4
✓ Branch 0 taken 18698203 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52671 times.
✓ Branch 3 taken 18645532 times.
18698298 if (open_tables(thd, &tables, &thd->lex->table_count, flags,
6969 &prelocking_strategy))
6970 52671 goto end;
6971
6972
3/4
✓ Branch 0 taken 18645223 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 18645127 times.
18645532 if (open_secondary_engine_tables(thd, flags)) goto end;
6973
6974 18645127 return false;
6975 52767 end:
6976 /*
6977 No need to commit/rollback the statement transaction: it's
6978 either not started or we're filling in an INFORMATION_SCHEMA
6979 table on the fly, and thus mustn't manipulate with the
6980 transaction of the enclosing statement.
6981 */
6982
5/6
✓ Branch 0 taken 1015 times.
✓ Branch 1 taken 51753 times.
✓ Branch 2 taken 1008 times.
✓ Branch 3 taken 7 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1008 times.
52767 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
6983 (thd->state_flags & Open_tables_state::BACKUPS_AVAIL) ||
6984 thd->in_sub_stmt);
6985
1/2
✓ Branch 0 taken 52766 times.
✗ Branch 1 not taken.
52768 close_thread_tables(thd);
6986 /* Don't keep locks for a failed statement. */
6987
1/2
✓ Branch 0 taken 52770 times.
✗ Branch 1 not taken.
52766 thd->mdl_context.rollback_to_savepoint(mdl_savepoint);
6988
6989 52770 return true; /* purecov: inspected */
6990 18697897 }
6991
6992 /*
6993 Mark all real tables in the list as free for reuse.
6994
6995 SYNOPSIS
6996 mark_real_tables_as_free_for_reuse()
6997 thd - thread context
6998 table - head of the list of tables
6999
7000 DESCRIPTION
7001 Marks all real tables in the list (i.e. not views, derived
7002 or schema tables) as free for reuse.
7003 */
7004
7005 2024336 static void mark_real_tables_as_free_for_reuse(TABLE_LIST *table_list) {
7006 TABLE_LIST *table;
7007
2/2
✓ Branch 0 taken 25512 times.
✓ Branch 1 taken 2024336 times.
2049848 for (table = table_list; table; table = table->next_global)
7008
2/2
✓ Branch 0 taken 25319 times.
✓ Branch 1 taken 193 times.
25512 if (!table->is_placeholder()) {
7009 25319 table->table->query_id = 0;
7010 }
7011
2/2
✓ Branch 0 taken 25512 times.
✓ Branch 1 taken 2024336 times.
2049848 for (table = table_list; table; table = table->next_global)
7012
5/6
✓ Branch 0 taken 25319 times.
✓ Branch 1 taken 193 times.
✓ Branch 2 taken 25319 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25319 times.
✓ Branch 5 taken 193 times.
25512 if (!table->is_placeholder() && table->table->db_stat) {
7013 /*
7014 Detach children of MyISAMMRG tables used in
7015 sub-statements, they will be reattached at open.
7016 This has to be done in a separate loop to make sure
7017 that children have had their query_id cleared.
7018 */
7019 25319 table->table->file->ha_extra(HA_EXTRA_DETACH_CHILDREN);
7020 }
7021 2024336 }
7022
7023 /**
7024 Lock all tables in a list.
7025
7026 @param thd Thread handler
7027 @param tables Tables to lock
7028 @param count Number of opened tables
7029 @param flags Options (see mysql_lock_tables() for details)
7030
7031 You can't call lock_tables() while holding thr_lock locks, as
7032 this would break the dead-lock-free handling thr_lock gives us.
7033 You must always get all needed locks at once.
7034
7035 If the query for which we are calling this function is marked as
7036 requiring prelocking, this function will change
7037 locked_tables_mode to LTM_PRELOCKED.
7038
7039 @retval false Success.
7040 @retval true A lock wait timeout, deadlock or out of memory.
7041 */
7042
7043 29610575 bool lock_tables(THD *thd, TABLE_LIST *tables, uint count, uint flags) {
7044 TABLE_LIST *table;
7045
7046
1/2
✓ Branch 0 taken 29612586 times.
✗ Branch 1 not taken.
29610575 DBUG_TRACE;
7047 /*
7048 We can't meet statement requiring prelocking if we already
7049 in prelocked mode.
7050 */
7051
3/4
✓ Branch 0 taken 792727 times.
✓ Branch 1 taken 28819859 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 792770 times.
29612586 assert(thd->locked_tables_mode <= LTM_LOCK_TABLES ||
7052 !thd->lex->requires_prelocking());
7053
7054 /*
7055 lock_tables() should not be called if this statement has
7056 already locked its tables.
7057 */
7058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 29612629 times.
29612629 assert(thd->lex->lock_tables_state == Query_tables_list::LTS_NOT_LOCKED);
7059
7060
6/6
✓ Branch 0 taken 17181463 times.
✓ Branch 1 taken 12431166 times.
✓ Branch 2 taken 17174850 times.
✓ Branch 3 taken 6552 times.
✓ Branch 4 taken 17174850 times.
✓ Branch 5 taken 12437718 times.
29612629 if (!tables && !thd->lex->requires_prelocking()) {
7061 /*
7062 Even though we are not really locking any tables mark this
7063 statement as one that has locked its tables, so we won't
7064 call this function second time for the same execution of
7065 the same statement.
7066 */
7067 17174850 thd->lex->lock_tables_state = Query_tables_list::LTS_LOCKED;
7068
1/2
✓ Branch 0 taken 17174975 times.
✗ Branch 1 not taken.
17174850 int ret = thd->decide_logging_format(tables);
7069 17174975 return ret;
7070 }
7071
7072 /*
7073 Check for thd->locked_tables_mode to avoid a redundant
7074 and harmful attempt to lock the already locked tables again.
7075 Checking for thd->lock is not enough in some situations. For example,
7076 if a stored function contains
7077 "drop table t3; create temporary t3 ..; insert into t3 ...;"
7078 thd->lock may be 0 after drop tables, whereas locked_tables_mode
7079 is still on. In this situation an attempt to lock temporary
7080 table t3 will lead to a memory leak.
7081 */
7082
2/2
✓ Branch 0 taken 12368193 times.
✓ Branch 1 taken 69525 times.
12437718 if (!thd->locked_tables_mode) {
7083
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12368193 times.
12368193 assert(thd->lock == nullptr); // You must lock everything at once
7084 TABLE **start, **ptr;
7085
7086
2/4
✓ Branch 0 taken 12368012 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 12368012 times.
12368193 if (!(ptr = start = (TABLE **)thd->alloc(sizeof(TABLE *) * count)))
7087 return true;
7088
2/2
✓ Branch 0 taken 16036219 times.
✓ Branch 1 taken 12368298 times.
28404517 for (table = tables; table; table = table->next_global) {
7089
4/4
✓ Branch 0 taken 15232967 times.
✓ Branch 1 taken 803538 times.
✓ Branch 2 taken 15232496 times.
✓ Branch 3 taken 804009 times.
31269186 if (!table->is_placeholder() &&
7090 /*
7091 Do not call handler::store_lock()/external_lock() for temporary
7092 tables from prelocking list.
7093
7094 Prelocking algorithm does not add element for a table to the
7095 prelocking list if it finds that the routine that uses the table can
7096 create it as a temporary during its execution. Note that such
7097 routine actually can use existing temporary table if its CREATE
7098 TEMPORARY TABLE has IF NOT EXISTS clause. For such tables we rely on
7099 calls to handler::start_stmt() done by routine's substatement when
7100 it accesses the table to inform storage engine about table
7101 participation in transaction and type of operation carried out,
7102 instead of calls to handler::store_lock()/external_lock() done at
7103 prelocking stage.
7104
7105 In cases when statement uses two routines one of which can create
7106 temporary table and modifies it, while another only reads from this
7107 table, storage engine might be confused about real operation type
7108 performed by the whole statement. Calls to
7109 handler::store_lock()/external_lock() done at prelocking stage will
7110 inform SE only about read part, while information about modification
7111 will be delayed until handler::start_stmt() call during execution of
7112 the routine doing modification. InnoDB considers this breaking of
7113 promise about operation type and fails on assertion.
7114
7115 To avoid this problem we try to handle both the cases when temporary
7116 table can be created by routine and the case when it is created
7117 outside of routine and only accessed by it, uniformly. We don't call
7118 handler::store_lock()/external_lock() for temporary tables used by
7119 routines at prelocking stage and rely on calls to
7120 handler::start_stmt(), which happen during substatement execution,
7121 to pass correct information about operation type instead.
7122 */
7123
2/2
✓ Branch 0 taken 25378 times.
✓ Branch 1 taken 15207589 times.
15232967 !(table->prelocking_placeholder &&
7124
2/2
✓ Branch 0 taken 24902 times.
✓ Branch 1 taken 476 times.
25378 table->table->s->tmp_table != NO_TMP_TABLE)) {
7125 15232496 *(ptr++) = table->table;
7126 }
7127 }
7128
7129
3/4
✓ Branch 0 taken 10477081 times.
✓ Branch 1 taken 1891039 times.
✓ Branch 2 taken 10477548 times.
✗ Branch 3 not taken.
12368298 DEBUG_SYNC(thd, "before_lock_tables_takes_lock");
7130
7131 12368307 if (!(thd->lock =
7132
3/4
✓ Branch 0 taken 12368307 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1075 times.
✓ Branch 3 taken 12367232 times.
12368587 mysql_lock_tables(thd, start, (uint)(ptr - start), flags)))
7133 1075 return true;
7134
7135
3/4
✓ Branch 0 taken 10475754 times.
✓ Branch 1 taken 1891311 times.
✓ Branch 2 taken 10476445 times.
✗ Branch 3 not taken.
12367232 DEBUG_SYNC(thd, "after_lock_tables_takes_lock");
7136
7137
4/4
✓ Branch 0 taken 2024383 times.
✓ Branch 1 taken 10342903 times.
✓ Branch 2 taken 2024266 times.
✓ Branch 3 taken 10343020 times.
14392139 if (thd->lex->requires_prelocking() &&
7138
2/2
✓ Branch 0 taken 2024266 times.
✓ Branch 1 taken 117 times.
2024383 thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
7139 2024266 TABLE_LIST *first_not_own = thd->lex->first_not_own_table();
7140 /*
7141 We just have done implicit LOCK TABLES, and now we have
7142 to emulate first open_and_lock_tables() after it.
7143
7144 When open_and_lock_tables() is called for a single table out of
7145 a table list, the 'next_global' chain is temporarily broken. We
7146 may not find 'first_not_own' before the end of the "list".
7147 Look for example at those places where open_n_lock_single_table()
7148 is called. That function implements the temporary breaking of
7149 a table list for opening a single table.
7150 */
7151
4/4
✓ Branch 0 taken 2059875 times.
✓ Branch 1 taken 2007750 times.
✓ Branch 2 taken 2043359 times.
✓ Branch 3 taken 16516 times.
4067625 for (table = tables; table && table != first_not_own;
7152 2043359 table = table->next_global) {
7153
2/2
✓ Branch 0 taken 2042863 times.
✓ Branch 1 taken 496 times.
2043359 if (!table->is_placeholder()) {
7154 2042863 table->table->query_id = thd->query_id;
7155
3/6
✓ Branch 0 taken 2042863 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2042863 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2042863 times.
2042863 if (check_lock_and_start_stmt(thd, thd->lex, table)) {
7156 mysql_unlock_tables(thd, thd->lock);
7157 thd->lock = nullptr;
7158 return true;
7159 }
7160 }
7161 }
7162 /*
7163 Let us mark all tables which don't belong to the statement itself,
7164 and was marked as occupied during open_tables() as free for reuse.
7165 */
7166
1/2
✓ Branch 0 taken 2024266 times.
✗ Branch 1 not taken.
2024266 mark_real_tables_as_free_for_reuse(first_not_own);
7167
5/8
✓ Branch 0 taken 2024266 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2024266 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 2024265 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2024266 DBUG_PRINT("info", ("locked_tables_mode= LTM_PRELOCKED"));
7168
1/2
✓ Branch 0 taken 2024266 times.
✗ Branch 1 not taken.
2024266 thd->enter_locked_tables_mode(LTM_PRELOCKED);
7169 }
7170 } else {
7171 /*
7172 When we implicitly open DD tables used by a IS query in LOCK TABLE mode,
7173 we do not go through mysql_lock_tables(), which sets lock type to use
7174 by SE. Here, we request SE to use read lock for these implicitly opened
7175 DD tables using ha_external_lock().
7176
7177 TODO: In PRELOCKED under LOCKED TABLE mode, if sub-statement is a IS
7178 query then for DD table ha_external_lock is called more than once.
7179 This works for now as in this mode each sub-statement gets its own
7180 brand new TABLE instances for each table.
7181 Allocating a brand new TABLE instances for each sub-statement is
7182 a resources wastage. Once this issue is fixed, following code
7183 should be adjusted to not to call ha_external_lock in sub-statement
7184 mode (similar to how code in close_thread_table() behaves).
7185 */
7186
2/2
✓ Branch 0 taken 17593 times.
✓ Branch 1 taken 51618 times.
69525 if (in_LTM(thd)) {
7187
2/2
✓ Branch 0 taken 102214 times.
✓ Branch 1 taken 17593 times.
119807 for (table = tables; table; table = table->next_global) {
7188 102214 TABLE *tbl = table->table;
7189
6/6
✓ Branch 0 taken 78208 times.
✓ Branch 1 taken 24006 times.
✓ Branch 2 taken 73867 times.
✓ Branch 3 taken 4341 times.
✓ Branch 4 taken 73867 times.
✓ Branch 5 taken 28347 times.
102214 if (tbl && belongs_to_dd_table(table)) {
7190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 73867 times.
73867 assert(tbl->file->get_lock_type() == F_UNLCK);
7191
1/2
✓ Branch 0 taken 73867 times.
✗ Branch 1 not taken.
73867 tbl->file->init_table_handle_for_HANDLER();
7192
1/2
✓ Branch 0 taken 73867 times.
✗ Branch 1 not taken.
73867 tbl->file->ha_external_lock(thd, F_RDLCK);
7193 }
7194 }
7195 }
7196
7197 69211 TABLE_LIST *first_not_own = thd->lex->first_not_own_table();
7198 /*
7199 When open_and_lock_tables() is called for a single table out of
7200 a table list, the 'next_global' chain is temporarily broken. We
7201 may not find 'first_not_own' before the end of the "list".
7202 Look for example at those places where open_n_lock_single_table()
7203 is called. That function implements the temporary breaking of
7204 a table list for opening a single table.
7205 */
7206
4/4
✓ Branch 0 taken 154566 times.
✓ Branch 1 taken 69129 times.
✓ Branch 2 taken 154520 times.
✓ Branch 3 taken 46 times.
223695 for (table = tables; table && table != first_not_own;
7207 154484 table = table->next_global) {
7208
2/2
✓ Branch 0 taken 24522 times.
✓ Branch 1 taken 129998 times.
154520 if (table->is_placeholder()) continue;
7209
7210 /*
7211 In a stored function or trigger we should ensure that we won't change
7212 a table that is already used by the calling statement.
7213 */
7214
4/4
✓ Branch 0 taken 52258 times.
✓ Branch 1 taken 77740 times.
✓ Branch 2 taken 40357 times.
✓ Branch 3 taken 89641 times.
182256 if (thd->locked_tables_mode >= LTM_PRELOCKED &&
7215
2/2
✓ Branch 0 taken 40357 times.
✓ Branch 1 taken 11901 times.
52258 table->lock_descriptor().type >= TL_WRITE_ALLOW_WRITE) {
7216
2/2
✓ Branch 0 taken 117653 times.
✓ Branch 1 taken 40338 times.
157991 for (TABLE *opentab = thd->open_tables; opentab;
7217 117634 opentab = opentab->next) {
7218
4/4
✓ Branch 0 taken 42008 times.
✓ Branch 1 taken 75645 times.
✓ Branch 2 taken 39967 times.
✓ Branch 3 taken 2041 times.
117653 if (table->table->s == opentab->s && opentab->query_id &&
7219
2/2
✓ Branch 0 taken 19 times.
✓ Branch 1 taken 39948 times.
39967 table->table->query_id != opentab->query_id) {
7220 19 my_error(ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG, MYF(0),
7221
1/2
✓ Branch 0 taken 19 times.
✗ Branch 1 not taken.
19 table->table->s->table_name.str);
7222 19 return true;
7223 }
7224 }
7225 }
7226
7227
4/6
✓ Branch 0 taken 129979 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 129979 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 17 times.
✓ Branch 5 taken 129962 times.
129979 if (check_lock_and_start_stmt(thd, thd->lex, table)) {
7228 17 return true;
7229 }
7230 }
7231 /*
7232 If we are under explicit LOCK TABLES and our statement requires
7233 prelocking, we should mark all "additional" tables as free for use
7234 and enter prelocked mode.
7235 */
7236
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 69105 times.
69175 if (thd->lex->requires_prelocking()) {
7237
1/2
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
70 mark_real_tables_as_free_for_reuse(first_not_own);
7238
3/8
✓ Branch 0 taken 70 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 70 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 70 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
70 DBUG_PRINT("info",
7239 ("thd->locked_tables_mode= LTM_PRELOCKED_UNDER_LOCK_TABLES"));
7240 70 thd->locked_tables_mode = LTM_PRELOCKED_UNDER_LOCK_TABLES;
7241 }
7242 }
7243
7244 /*
7245 Mark the statement as having tables locked. For purposes
7246 of Query_tables_list::lock_tables_state we treat any
7247 statement which passes through lock_tables() as such.
7248 */
7249 12436461 thd->lex->lock_tables_state = Query_tables_list::LTS_LOCKED;
7250
7251
1/2
✓ Branch 0 taken 12435889 times.
✗ Branch 1 not taken.
12436461 int ret = thd->decide_logging_format(tables);
7252 12435889 return ret;
7253 29611975 }
7254
7255 /**
7256 Simplified version of lock_tables() call to be used for locking
7257 data-dictionary tables when reading or storing data-dictionary
7258 objects.
7259
7260 @note The main reason why this function exists is that it avoids
7261 allocating temporary buffer on memory root of statement.
7262 As result it can be called many times (e.g. thousands)
7263 during DDL statement execution without hogging memory.
7264 */
7265
7266 20033671 bool lock_dictionary_tables(THD *thd, TABLE_LIST *tables, uint count,
7267 uint flags) {
7268
1/2
✓ Branch 0 taken 20033687 times.
✗ Branch 1 not taken.
20033671 DBUG_TRACE;
7269
7270 // We always open at least one DD table.
7271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20033687 times.
20033687 assert(tables);
7272 /*
7273 This function is supposed to be called after backing up and resetting
7274 to clean state Open_tables_state and Query_table_lists contexts.
7275 */
7276
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20033687 times.
20033687 assert(thd->locked_tables_mode == LTM_NONE);
7277
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20033684 times.
20033687 assert(!thd->lex->requires_prelocking());
7278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20033684 times.
20033684 assert(thd->lex->lock_tables_state == Query_tables_list::LTS_NOT_LOCKED);
7279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20033684 times.
20033684 assert(thd->lock == nullptr);
7280
7281 TABLE **start, **ptr;
7282
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 20033684 times.
20033684 if (!(ptr = start = (TABLE **)my_alloca(sizeof(TABLE *) * count)))
7283 return true;
7284
7285
2/2
✓ Branch 0 taken 90828463 times.
✓ Branch 1 taken 20033702 times.
110862165 for (TABLE_LIST *table = tables; table; table = table->next_global) {
7286 // Data-dictionary tables must be base tables.
7287
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 90828481 times.
90828463 assert(!table->is_placeholder());
7288
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90828481 times.
90828481 assert(table->table->s->tmp_table == NO_TMP_TABLE);
7289 // There should be no prelocking when DD code uses this call.
7290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 90828481 times.
90828481 assert(!table->prelocking_placeholder);
7291 90828481 *(ptr++) = table->table;
7292 }
7293
7294
3/4
✓ Branch 0 taken 18881850 times.
✓ Branch 1 taken 1151831 times.
✓ Branch 2 taken 18881861 times.
✗ Branch 3 not taken.
20033702 DEBUG_SYNC(thd, "before_lock_dictionary_tables_takes_lock");
7295
7296
2/4
✓ Branch 0 taken 20033682 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 20033682 times.
20033692 if (!(thd->lock = mysql_lock_tables(thd, start, (uint)(ptr - start), flags)))
7297 return true;
7298
7299 20033682 thd->lex->lock_tables_state = Query_tables_list::LTS_LOCKED;
7300
7301 20033682 return false;
7302 20033682 }
7303
7304 /**
7305 Prepare statement for reopening of tables and recalculation of set of
7306 prelocked tables.
7307
7308 @param[in] thd Thread context.
7309 @param[in,out] tables List of tables which we were trying to open
7310 and lock.
7311 @param[in] start_of_statement_svp MDL savepoint which represents the set
7312 of metadata locks which the current transaction
7313 managed to acquire before execution of the current
7314 statement and to which we should revert before
7315 trying to reopen tables. NULL if no metadata locks
7316 were held and thus all metadata locks should be
7317 released.
7318 */
7319
7320 36 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables,
7321 const MDL_savepoint &start_of_statement_svp) {
7322 36 TABLE_LIST *first_not_own_table = thd->lex->first_not_own_table();
7323 TABLE_LIST *tmp;
7324
7325 /*
7326 If table list consists only from tables from prelocking set, table list
7327 for new attempt should be empty, so we have to update list's root pointer.
7328 */
7329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 36 times.
36 if (first_not_own_table == *tables) *tables = nullptr;
7330 36 thd->lex->chop_off_not_own_tables();
7331
1/2
✓ Branch 0 taken 36 times.
✗ Branch 1 not taken.
36 sp_remove_not_own_routines(thd->lex);
7332
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 36 times.
79 for (tmp = *tables; tmp; tmp = tmp->next_global) {
7333 43 tmp->table = nullptr;
7334 43 tmp->mdl_request.ticket = nullptr;
7335 /* We have to cleanup translation tables of views. */
7336 43 tmp->cleanup_items();
7337 }
7338 /*
7339 No need to commit/rollback the statement transaction: it's
7340 either not started or we're filling in an INFORMATION_SCHEMA
7341 table on the fly, and thus mustn't manipulate with the
7342 transaction of the enclosing statement.
7343 */
7344
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 35 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
36 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT) ||
7345 (thd->state_flags & Open_tables_state::BACKUPS_AVAIL));
7346 36 close_thread_tables(thd);
7347 36 thd->mdl_context.rollback_to_savepoint(start_of_statement_svp);
7348 36 }
7349
7350 /**
7351 Open a single table without table caching and don't add it to
7352 THD::open_tables. Depending on the 'add_to_temporary_tables_list' value,
7353 the opened TABLE instance will be added to THD::temporary_tables list.
7354
7355 @param thd Thread context.
7356 @param path Path (without .frm)
7357 @param db Database name.
7358 @param table_name Table name.
7359 @param add_to_temporary_tables_list Specifies if the opened TABLE
7360 instance should be linked into
7361 THD::temporary_tables list.
7362 @param open_in_engine Indicates that we need to open table
7363 in storage engine in addition to
7364 constructing TABLE object for it.
7365 @param table_def A data-dictionary Table-object describing
7366 table to be used for opening.
7367
7368 @note This function is used:
7369 - by alter_table() to open a temporary table;
7370 - when creating a temporary table with CREATE TEMPORARY TABLE.
7371
7372 @return TABLE instance for opened table.
7373 @retval NULL on error.
7374 */
7375
7376 153641 TABLE *open_table_uncached(THD *thd, const char *path, const char *db,
7377 const char *table_name,
7378 bool add_to_temporary_tables_list,
7379 bool open_in_engine, const dd::Table &table_def) {
7380 TABLE *tmp_table;
7381 TABLE_SHARE *share;
7382 char cache_key[MAX_DBKEY_LENGTH], *saved_cache_key, *tmp_path;
7383 size_t key_length;
7384
1/2
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
153641 DBUG_TRACE;
7385
5/8
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 153641 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 153640 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
153641 DBUG_PRINT("enter", ("table: '%s'.'%s' path: '%s' server_id: %u "
7386 "pseudo_thread_id: %lu",
7387 db, table_name, path, (uint)thd->server_id,
7388 (ulong)thd->variables.pseudo_thread_id));
7389
7390 /* Create the cache_key for temporary tables */
7391
1/2
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
153641 key_length = create_table_def_key_tmp(thd, db, table_name, cache_key);
7392
7393
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 153641 times.
153641 if (!(tmp_table = (TABLE *)my_malloc(
7394 key_memory_TABLE,
7395
1/2
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
153641 sizeof(*tmp_table) + sizeof(*share) + strlen(path) + 1 + key_length,
7396 MYF(MY_WME))))
7397 return nullptr; /* purecov: inspected */
7398
7399 #ifndef NDEBUG
7400 // In order to let purge thread callback call open_table_uncached()
7401 // we cannot grab LOCK_open here, as that will cause a deadlock.
7402
7403 // The assert below safeguards against opening a table which is
7404 // already found in the table definition cache. Iff the table will
7405 // be opened in the SE below, we may get two conflicting copies of
7406 // SE private data in the two table_shares.
7407
7408 // By only grabbing LOCK_open and check the assert only when
7409 // open_in_engine is true, we safeguard the engine private data while
7410 // also allowing the purge threads callbacks since they always call
7411 // with open_in_engine=false.
7412
2/2
✓ Branch 0 taken 68139 times.
✓ Branch 1 taken 85502 times.
153641 if (open_in_engine) {
7413
1/2
✓ Branch 0 taken 68139 times.
✗ Branch 1 not taken.
68139 mysql_mutex_lock(&LOCK_open);
7414
3/6
✓ Branch 0 taken 68139 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68139 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 68139 times.
68139 assert(table_def_cache->count(string(cache_key, key_length)) == 0);
7415
1/2
✓ Branch 0 taken 68139 times.
✗ Branch 1 not taken.
68139 mysql_mutex_unlock(&LOCK_open);
7416 }
7417 #endif
7418
7419 153641 share = (TABLE_SHARE *)(tmp_table + 1);
7420 153641 tmp_path = (char *)(share + 1);
7421 153641 saved_cache_key = my_stpcpy(tmp_path, path) + 1;
7422 153641 memcpy(saved_cache_key, cache_key, key_length);
7423
7424 153641 init_tmp_table_share(thd, share, saved_cache_key, key_length,
7425
1/2
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
153641 strend(saved_cache_key) + 1, tmp_path, nullptr);
7426
7427
2/4
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 153641 times.
153641 if (open_table_def(thd, share, table_def)) {
7428 /* No need to lock share->mutex as this is not needed for tmp tables */
7429 free_table_share(share);
7430 destroy(tmp_table);
7431 my_free(tmp_table);
7432 return nullptr;
7433 }
7434
7435 #ifdef HAVE_PSI_TABLE_INTERFACE
7436
1/2
✓ Branch 0 taken 153641 times.
✗ Branch 1 not taken.
153641 share->m_psi = PSI_TABLE_CALL(get_table_share)(true, share);
7437 #else
7438 share->m_psi = NULL;
7439 #endif
7440
7441
7/8
✓ Branch 0 taken 68139 times.
✓ Branch 1 taken 85502 times.
✓ Branch 2 taken 68139 times.
✓ Branch 3 taken 85502 times.
✓ Branch 4 taken 153641 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 10 times.
✓ Branch 7 taken 153631 times.
153641 if (open_table_from_share(
7442 thd, share, table_name,
7443 open_in_engine
7444 ? (uint)(HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX)
7445 : 0,
7446 EXTRA_RECORD, ha_open_options, tmp_table,
7447 /*
7448 Set "is_create_table" if the table does not
7449 exist in SE
7450 */
7451 (open_in_engine ? false : true), &table_def)) {
7452 /* No need to lock share->mutex as this is not needed for tmp tables */
7453
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 free_table_share(share);
7454 10 destroy(tmp_table);
7455
1/2
✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
10 my_free(tmp_table);
7456 10 return nullptr;
7457 }
7458
7459 153631 tmp_table->reginfo.lock_type = TL_WRITE; // Simulate locked
7460 153631 share->tmp_table =
7461
2/2
✓ Branch 0 taken 121922 times.
✓ Branch 1 taken 31709 times.
153631 (tmp_table->file->has_transactions() ? TRANSACTIONAL_TMP_TABLE
7462 : NON_TRANSACTIONAL_TMP_TABLE);
7463
7464
2/2
✓ Branch 0 taken 153427 times.
✓ Branch 1 taken 204 times.
153631 if (add_to_temporary_tables_list) {
7465 153427 tmp_table->set_tmp_dd_table_ptr(&table_def);
7466
1/2
✓ Branch 0 taken 153427 times.
✗ Branch 1 not taken.
153427 tmp_table->set_binlog_drop_if_temp(
7467
5/6
✓ Branch 0 taken 153427 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 69761 times.
✓ Branch 3 taken 83666 times.
✓ Branch 4 taken 3593 times.
✓ Branch 5 taken 66168 times.
223187 !thd->is_current_stmt_binlog_disabled() &&
7468 69761 !thd->is_current_stmt_binlog_format_row());
7469 /* growing temp list at the head */
7470
1/2
✓ Branch 0 taken 153427 times.
✗ Branch 1 not taken.
153427 mysql_mutex_lock(&thd->LOCK_temporary_tables);
7471 153427 tmp_table->next = thd->temporary_tables;
7472
2/2
✓ Branch 0 taken 5704 times.
✓ Branch 1 taken 147723 times.
153427 if (tmp_table->next) tmp_table->next->prev = tmp_table;
7473 153427 thd->temporary_tables = tmp_table;
7474 153427 thd->temporary_tables->prev = nullptr;
7475
2/2
✓ Branch 0 taken 2580 times.
✓ Branch 1 taken 150847 times.
153427 if (thd->slave_thread) {
7476 2580 ++atomic_replica_open_temp_tables;
7477
1/2
✓ Branch 0 taken 2580 times.
✗ Branch 1 not taken.
2580 ++thd->rli_slave->get_c_rli()->atomic_channel_open_temp_tables;
7478 }
7479
1/2
✓ Branch 0 taken 153426 times.
✗ Branch 1 not taken.
153427 mysql_mutex_unlock(&thd->LOCK_temporary_tables);
7480 }
7481 153630 tmp_table->pos_in_table_list = nullptr;
7482
7483
1/2
✓ Branch 0 taken 153630 times.
✗ Branch 1 not taken.
153630 tmp_table->set_created();
7484
7485
5/8
✓ Branch 0 taken 153630 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 153630 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 153629 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
153630 DBUG_PRINT("tmptable", ("opened table: '%s'.'%s' %p", tmp_table->s->db.str,
7486 tmp_table->s->table_name.str, tmp_table));
7487 153630 return tmp_table;
7488 153640 }
7489
7490 /**
7491 Delete a temporary table.
7492
7493 @param thd Thread handle
7494 @param base Handlerton for table to be deleted.
7495 @param path Path to the table to be deleted (without
7496 an extension).
7497 @param table_def dd::Table object describing temporary table
7498 to be deleted.
7499
7500 @retval false - success.
7501 @retval true - failure.
7502 */
7503
7504 48563 bool rm_temporary_table(THD *thd, handlerton *base, const char *path,
7505 const dd::Table *table_def) {
7506 48563 bool error = false;
7507 handler *file;
7508
1/2
✓ Branch 0 taken 48563 times.
✗ Branch 1 not taken.
48563 DBUG_TRACE;
7509
7510 145689 file = get_new_handler((TABLE_SHARE *)nullptr,
7511
2/4
✓ Branch 0 taken 48563 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48563 times.
✗ Branch 3 not taken.
48563 table_def->partition_type() != dd::Table::PT_NONE,
7512 thd->mem_root, base);
7513
4/8
✓ Branch 0 taken 48563 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 48563 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 48563 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 48563 times.
48563 if (file && file->ha_delete_table(path, table_def)) {
7514 error = true;
7515 LogErr(WARNING_LEVEL, ER_FAILED_TO_REMOVE_TEMP_TABLE, path, my_errno());
7516 }
7517 48563 destroy(file);
7518 48563 return error;
7519 48563 }
7520
7521 /*****************************************************************************
7522 * The following find_field_in_XXX procedures implement the core of the
7523 * name resolution functionality. The entry point to resolve a column name in a
7524 * list of tables is 'find_field_in_tables'. It calls 'find_field_in_table_ref'
7525 * for each table reference. In turn, depending on the type of table reference,
7526 * 'find_field_in_table_ref' calls one of the 'find_field_in_XXX' procedures
7527 * below specific for the type of table reference.
7528 *
7529 * @todo: Refactor the error handling system used by these functions, so that
7530 * it is clear when an error is reported and when an empty reference
7531 * is returned.
7532 *
7533 ******************************************************************************/
7534
7535 /* Special Field pointers as return values of find_field_in_XXX functions. */
7536 Field *not_found_field = (Field *)0x1;
7537 Field *view_ref_found = (Field *)0x2;
7538
7539 #define WRONG_GRANT (Field *)-1
7540
7541 /**
7542 Find a temporary table specified by TABLE_LIST instance in the cache and
7543 prepare its TABLE instance for use.
7544
7545 This function tries to resolve this table in the list of temporary tables
7546 of this thread. Temporary tables are thread-local and "shadow" base
7547 tables with the same name.
7548
7549 @note In most cases one should use open_temporary_tables() instead
7550 of this call.
7551
7552 @note One should finalize process of opening temporary table for table
7553 list element by calling open_and_process_table(). This function
7554 is responsible for table version checking and handling of merge
7555 tables.
7556
7557 @note We used to check global_read_lock before opening temporary tables.
7558 However, that limitation was artificial and is removed now.
7559
7560 @return Error status.
7561 @retval false On success. If a temporary table exists for the given
7562 key, tl->table is set.
7563 @retval true On error. my_error() has been called.
7564 */
7565
7566 12793666 bool open_temporary_table(THD *thd, TABLE_LIST *tl) {
7567
1/2
✓ Branch 0 taken 12794304 times.
✗ Branch 1 not taken.
12793666 DBUG_TRACE;
7568
5/8
✓ Branch 0 taken 12794188 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12794265 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 86 times.
✓ Branch 5 taken 12794179 times.
✓ Branch 6 taken 104 times.
✗ Branch 7 not taken.
12794304 DBUG_PRINT("enter", ("table: '%s'.'%s'", tl->db, tl->table_name));
7569
7570 /*
7571 Code in open_table() assumes that TABLE_LIST::table can
7572 be non-zero only for pre-opened temporary tables.
7573 */
7574
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12794283 times.
12794283 assert(tl->table == nullptr);
7575
7576 /*
7577 This function should not be called for cases when derived or I_S
7578 tables can be met since table list elements for such tables can
7579 have invalid db or table name.
7580 Instead open_temporary_tables() should be used.
7581 */
7582
3/4
✓ Branch 0 taken 12793784 times.
✓ Branch 1 taken 501 times.
✓ Branch 2 taken 12793801 times.
✗ Branch 3 not taken.
12794283 assert(!tl->is_view_or_derived() && !tl->schema_table);
7583
7584
2/2
✓ Branch 0 taken 1062008 times.
✓ Branch 1 taken 11731793 times.
12793801 if (tl->open_type == OT_BASE_ONLY) {
7585
5/8
✓ Branch 0 taken 1062001 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1061992 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24 times.
✓ Branch 5 taken 1061968 times.
✓ Branch 6 taken 24 times.
✗ Branch 7 not taken.
1062008 DBUG_PRINT("info", ("skip_temporary is set"));
7586 1061992 return false;
7587 }
7588
7589
1/2
✓ Branch 0 taken 11731821 times.
✗ Branch 1 not taken.
11731793 TABLE *table = find_temporary_table(thd, tl);
7590
7591 // Access to temporary tables is disallowed in XA transactions in
7592 // xa_detach_on_prepare=ON mode.
7593
2/2
✓ Branch 0 taken 291422 times.
✓ Branch 1 taken 11391984 times.
11683406 if ((tl->open_type == OT_TEMPORARY_ONLY ||
7594
3/4
✓ Branch 0 taken 291466 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 339978 times.
✓ Branch 3 taken 30 times.
631430 (table && table->s->tmp_table != NO_TMP_TABLE)) &&
7595
4/4
✓ Branch 0 taken 11683406 times.
✓ Branch 1 taken 48415 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11731943 times.
23755234 is_xa_tran_detached_on_prepare(thd) &&
7596
3/4
✓ Branch 0 taken 339977 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 339973 times.
339978 thd->get_transaction()->xid_state()->check_in_xa(false)) {
7597
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 my_error(ER_XA_TEMP_TABLE, MYF(0));
7598 4 return true;
7599 }
7600
7601
2/2
✓ Branch 0 taken 11439078 times.
✓ Branch 1 taken 292865 times.
11731943 if (!table) {
7602
2/2
✓ Branch 0 taken 47646 times.
✓ Branch 1 taken 11391432 times.
11439078 if (tl->open_type == OT_TEMPORARY_ONLY &&
7603
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 47646 times.
47646 tl->open_strategy == TABLE_LIST::OPEN_NORMAL) {
7604 my_error(ER_NO_SUCH_TABLE, MYF(0), tl->db, tl->table_name);
7605 return true;
7606 }
7607 11439078 return false;
7608 }
7609
7610
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 292864 times.
292865 if (tl->partition_names) {
7611 /* Partitioned temporary tables is not supported. */
7612
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 assert(!table->part_info);
7613
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_PARTITION_CLAUSE_ON_NONPARTITIONED, MYF(0));
7614 1 return true;
7615 }
7616
7617
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 292841 times.
292864 if (table->query_id) {
7618 /*
7619 We're trying to use the same temporary table twice in a query.
7620 Right now we don't support this because a temporary table is always
7621 represented by only one TABLE object in THD, and it can not be
7622 cloned. Emit an error for an unsupported behaviour.
7623 */
7624
7625
3/8
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 23 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 23 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
23 DBUG_PRINT("error", ("query_id: %lu server_id: %u pseudo_thread_id: %lu",
7626 (ulong)table->query_id, (uint)thd->server_id,
7627 (ulong)thd->variables.pseudo_thread_id));
7628
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 my_error(ER_CANT_REOPEN_TABLE, MYF(0), table->alias);
7629 23 return true;
7630 }
7631
7632 292841 table->query_id = thd->query_id;
7633 292841 thd->thread_specific_used = true;
7634
7635 292841 tl->set_updatable(); // It is not derived table nor non-updatable VIEW.
7636 292334 tl->set_insertable();
7637
7638
1/2
✓ Branch 0 taken 292333 times.
✗ Branch 1 not taken.
292341 table->reset();
7639
1/2
✓ Branch 0 taken 292336 times.
✗ Branch 1 not taken.
292333 table->init(thd, tl);
7640
7641
3/8
✓ Branch 0 taken 292340 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 292340 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 292340 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
292336 DBUG_PRINT("info", ("Using temporary table"));
7642 292339 return false;
7643 12793437 }
7644
7645 /**
7646 Pre-open temporary tables corresponding to table list elements.
7647
7648 @note One should finalize process of opening temporary tables
7649 by calling open_tables(). This function is responsible
7650 for table version checking and handling of merge tables.
7651
7652 @return Error status.
7653 @retval false On success. If a temporary tables exists for the
7654 given element, tl->table is set.
7655 @retval true On error. my_error() has been called.
7656 */
7657
7658 20255028 bool open_temporary_tables(THD *thd, TABLE_LIST *tl_list) {
7659 20255028 TABLE_LIST *first_not_own = thd->lex->first_not_own_table();
7660
1/2
✓ Branch 0 taken 20256048 times.
✗ Branch 1 not taken.
20255519 DBUG_TRACE;
7661
7662
4/4
✓ Branch 0 taken 12999221 times.
✓ Branch 1 taken 20254892 times.
✓ Branch 2 taken 12997396 times.
✓ Branch 3 taken 1825 times.
33254113 for (TABLE_LIST *tl = tl_list; tl && tl != first_not_own;
7663 12998065 tl = tl->next_global) {
7664 // Placeholder tables are processed during query execution
7665
2/2
✓ Branch 0 taken 12909512 times.
✓ Branch 1 taken 2803 times.
25909288 if (tl->is_view_or_derived() || tl->is_table_function() ||
7666
8/8
✓ Branch 0 taken 12911892 times.
✓ Branch 1 taken 85735 times.
✓ Branch 2 taken 12740596 times.
✓ Branch 3 taken 168916 times.
✓ Branch 4 taken 46 times.
✓ Branch 5 taken 12740605 times.
✓ Branch 6 taken 257502 times.
✓ Branch 7 taken 12740603 times.
25909942 tl->schema_table != nullptr || tl->is_recursive_reference())
7667 257502 continue;
7668
7669
3/4
✓ Branch 0 taken 12740591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28 times.
✓ Branch 3 taken 12740563 times.
12740603 if (open_temporary_table(thd, tl)) return true;
7670 }
7671
7672 20256717 return false;
7673 20256745 }
7674
7675 /*
7676 Find a field by name in a view that uses merge algorithm.
7677
7678 SYNOPSIS
7679 find_field_in_view()
7680 thd thread handler
7681 table_list view to search for 'name'
7682 name name of field
7683 ref expression substituted in VIEW should be passed
7684 using this reference (return view_ref_found)
7685 register_tree_change true if ref is not stack variable and we
7686 need register changes in item tree
7687
7688 RETURN
7689 0 field is not found
7690 view_ref_found found value in VIEW (real result is in *ref)
7691 # pointer to field - only for schema table fields
7692 */
7693
7694 2915600 static Field *find_field_in_view(THD *thd, TABLE_LIST *table_list,
7695 const char *name, Item **ref,
7696 bool register_tree_change) {
7697
1/2
✓ Branch 0 taken 2915600 times.
✗ Branch 1 not taken.
2915600 DBUG_TRACE;
7698
3/8
✓ Branch 0 taken 2915600 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2915599 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2915599 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
2915600 DBUG_PRINT("enter", ("view: '%s', field name: '%s', ref %p",
7699 table_list->alias, name, ref));
7700 2915599 Field_iterator_view field_it;
7701
1/2
✓ Branch 0 taken 2915598 times.
✗ Branch 1 not taken.
2915599 field_it.set(table_list);
7702
7703
4/6
✓ Branch 0 taken 2915592 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2915592 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2915592 times.
✗ Branch 5 not taken.
2915598 assert(table_list->schema_table_reformed ||
7704 (ref != nullptr && table_list->is_merged()));
7705
2/2
✓ Branch 0 taken 28061284 times.
✓ Branch 1 taken 2450 times.
28063732 for (; !field_it.end_of_fields(); field_it.next()) {
7706
4/6
✓ Branch 0 taken 28061284 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 28061283 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2913149 times.
✓ Branch 5 taken 25148134 times.
28061284 if (!my_strcasecmp(system_charset_info, field_it.name(), name)) {
7707 Item *item;
7708
7709 {
7710 /*
7711 Use own arena for Prepared Statements or data will be freed after
7712 PREPARE.
7713 */
7714 Prepared_stmt_arena_holder ps_arena_holder(
7715
4/4
✓ Branch 0 taken 2910846 times.
✓ Branch 1 taken 2303 times.
✓ Branch 2 taken 2064973 times.
✓ Branch 3 taken 845873 times.
5823995 thd, register_tree_change &&
7716
1/2
✓ Branch 0 taken 2913149 times.
✗ Branch 1 not taken.
5823995 thd->stmt_arena->is_stmt_prepare_or_first_stmt_execute());
7717
7718 /*
7719 create_item() may, or may not create a new Item, depending on
7720 the column reference. See create_view_field() for details.
7721 */
7722
1/2
✓ Branch 0 taken 2913150 times.
✗ Branch 1 not taken.
2913149 item = field_it.create_item(thd);
7723
7724
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2913150 times.
2913150 if (!item) return nullptr;
7725
1/2
✓ Branch 0 taken 2913150 times.
✗ Branch 1 not taken.
2913150 }
7726
7727 /*
7728 *ref != NULL means that *ref contains the item that we need to
7729 replace. If the item was aliased by the user, set the alias to
7730 the replacing item.
7731 We need to set alias on both ref itself and on ref real item.
7732 */
7733
6/6
✓ Branch 0 taken 2910847 times.
✓ Branch 1 taken 2303 times.
✓ Branch 2 taken 618926 times.
✓ Branch 3 taken 2291921 times.
✓ Branch 4 taken 618926 times.
✓ Branch 5 taken 2294224 times.
2913150 if (*ref && !(*ref)->item_name.is_autogenerated()) {
7734 618926 item->item_name = (*ref)->item_name;
7735
1/2
✓ Branch 0 taken 618926 times.
✗ Branch 1 not taken.
618926 item->real_item()->item_name = (*ref)->item_name;
7736 }
7737 2913150 *ref = item;
7738 // WL#6570 remove-after-qa
7739
3/4
✓ Branch 0 taken 2064986 times.
✓ Branch 1 taken 848163 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2064986 times.
2913150 assert(thd->stmt_arena->is_regular() || !thd->lex->is_exec_started());
7740
7741 2913149 return view_ref_found;
7742 }
7743 }
7744 2450 return nullptr;
7745 2915599 }
7746
7747 /**
7748 Find field by name in a NATURAL/USING join table reference.
7749
7750 @param thd thread handler
7751 @param table_ref table reference to search
7752 @param name name of field
7753 @param [in,out] ref if 'name' is resolved to a view field, ref is
7754 set to point to the found view field
7755 @param register_tree_change true if ref is not stack variable and we
7756 need register changes in item tree
7757 @param [out] actual_table The original table reference where the field
7758 belongs - differs from 'table_list' only for
7759 NATURAL/USING joins
7760
7761 DESCRIPTION
7762 Search for a field among the result fields of a NATURAL/USING join.
7763 Notice that this procedure is called only for non-qualified field
7764 names. In the case of qualified fields, we search directly the base
7765 tables of a natural join.
7766
7767 Sometimes when a field is found, it is checked for privileges according to
7768 THD::want_privilege and marked according to THD::mark_used_columns.
7769 But it is unclear when, so caller generally has to do the same.
7770
7771 RETURN
7772 NULL if the field was not found
7773 WRONG_GRANT if no access rights to the found field
7774 # Pointer to the found Field
7775 */
7776
7777 31899 static Field *find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref,
7778 const char *name, Item **ref,
7779 bool register_tree_change,
7780 TABLE_LIST **actual_table) {
7781
1/2
✓ Branch 0 taken 31899 times.
✗ Branch 1 not taken.
31899 List_iterator_fast<Natural_join_column> field_it(*(table_ref->join_columns));
7782 Natural_join_column *nj_col, *curr_nj_col;
7783 31899 Field *found_field = nullptr;
7784
1/2
✓ Branch 0 taken 31899 times.
✗ Branch 1 not taken.
31899 DBUG_TRACE;
7785
3/8
✓ Branch 0 taken 31899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31899 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 31899 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
31899 DBUG_PRINT("enter", ("field name: '%s', ref %p", name, ref));
7786
2/4
✓ Branch 0 taken 31899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 31899 times.
✗ Branch 3 not taken.
31899 assert(table_ref->is_natural_join && table_ref->join_columns);
7787
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31899 times.
31899 assert(*actual_table == nullptr);
7788
7789
2/2
✓ Branch 0 taken 1002538 times.
✓ Branch 1 taken 31892 times.
1034430 for (nj_col = nullptr, curr_nj_col = field_it++; curr_nj_col;
7790 1002531 curr_nj_col = field_it++) {
7791
4/6
✓ Branch 0 taken 1002538 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1002538 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 28084 times.
✓ Branch 5 taken 974454 times.
1002538 if (!my_strcasecmp(system_charset_info, curr_nj_col->name(), name)) {
7792
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 28077 times.
28084 if (nj_col) {
7793
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 my_error(ER_NON_UNIQ_ERROR, MYF(0), name, thd->where);
7794 7 return nullptr;
7795 }
7796 28077 nj_col = curr_nj_col;
7797 }
7798 }
7799
2/2
✓ Branch 0 taken 3822 times.
✓ Branch 1 taken 28070 times.
31892 if (!nj_col) return nullptr;
7800
7801
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 28056 times.
28070 if (nj_col->view_field) {
7802 Item *item;
7803
7804 {
7805
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 Prepared_stmt_arena_holder ps_arena_holder(thd, register_tree_change);
7806
7807 /*
7808 create_item() may, or may not create a new Item, depending on the
7809 column reference. See create_view_field() for details.
7810 */
7811
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 item = nj_col->create_item(thd);
7812
7813
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (!item) return nullptr;
7814
1/2
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
14 }
7815
7816 /*
7817 *ref != NULL means that *ref contains the item that we need to
7818 replace. If the item was aliased by the user, set the alias to
7819 the replacing item.
7820 We need to set alias on both ref itself and on ref real item.
7821 */
7822
5/6
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 13 times.
14 if (*ref && !(*ref)->item_name.is_autogenerated()) {
7823 1 item->item_name = (*ref)->item_name;
7824
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 item->real_item()->item_name = (*ref)->item_name;
7825 }
7826
7827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 assert(nj_col->table_field == nullptr);
7828
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (nj_col->table_ref->schema_table_reformed) {
7829 /*
7830 Translation table items are always Item_fields and fixed
7831 already('mysql_schema_table' function). So we can return
7832 ->field. It is used only for 'show & where' commands.
7833 */
7834 return ((Item_field *)(nj_col->view_field->item))->field;
7835 }
7836 14 *ref = item;
7837 // WL#6570 remove-after-qa
7838
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
14 assert(thd->stmt_arena->is_regular() || !thd->lex->is_exec_started());
7839 14 found_field = view_ref_found;
7840 } else {
7841 /* This is a base table. */
7842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28056 times.
28056 assert(nj_col->view_field == nullptr);
7843 /*
7844 This fix_fields is not necessary (initially this item is fixed by
7845 the Item_field constructor; after reopen_tables the Item_func_eq
7846 calls fix_fields on that item), it's just a check during table
7847 reopening for columns that was dropped by the concurrent connection.
7848 */
7849
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 28056 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 28056 times.
28056 if (!nj_col->table_field->fixed &&
7850 nj_col->table_field->fix_fields(thd, (Item **)&nj_col->table_field)) {
7851 DBUG_PRINT("info",
7852 ("column '%s' was dropped by the concurrent connection",
7853 nj_col->table_field->item_name.ptr()));
7854 return nullptr;
7855 }
7856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 28056 times.
28056 assert(nj_col->table_ref->table == nj_col->table_field->field->table);
7857 28056 found_field = nj_col->table_field->field;
7858 }
7859
7860 28070 *actual_table = nj_col->table_ref;
7861
7862 28070 return found_field;
7863 31899 }
7864
7865 /**
7866 Find field by name in a base table.
7867
7868 No privileges are checked, and the column is not marked in read_set/write_set.
7869
7870 @param table table where to search for the field
7871 @param name name of field
7872 @param allow_rowid do allow finding of "_rowid" field?
7873 @param[out] field_index_ptr position in field list (used to speedup
7874 lookup for fields in prepared tables)
7875
7876 @retval NULL field is not found
7877 @retval != NULL pointer to field
7878 */
7879
7880 53253338 Field *find_field_in_table(TABLE *table, const char *name, bool allow_rowid,
7881 uint *field_index_ptr) {
7882
1/2
✓ Branch 0 taken 53253402 times.
✗ Branch 1 not taken.
53253338 DBUG_TRACE;
7883
5/8
✓ Branch 0 taken 53253391 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53253381 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 724 times.
✓ Branch 5 taken 53252657 times.
✓ Branch 6 taken 724 times.
✗ Branch 7 not taken.
53253402 DBUG_PRINT("enter", ("table: '%s', field name: '%s'", table->alias, name));
7884
7885 53253381 Field **field_ptr = nullptr, *field;
7886
7887
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53253381 times.
53253381 if (!(field_ptr = table->field)) return nullptr;
7888
2/2
✓ Branch 0 taken 310345566 times.
✓ Branch 1 taken 224676 times.
310570242 for (; *field_ptr; ++field_ptr) {
7889 // NOTE: This should probably be strncollsp() instead of my_strcasecmp();
7890 // in particular, Ñ != N for my_strcasecmp(), which is not according to the
7891 // usual ai_ci rules. However, changing it would risk breaking existing
7892 // table definitions (which don't distinguish between N and Ñ), so we can
7893 // only do this when actually changing the system collation.
7894
3/4
✓ Branch 0 taken 310345549 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53028688 times.
✓ Branch 3 taken 257316861 times.
310345566 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
7895 53028688 break;
7896 }
7897
7898
3/4
✓ Branch 0 taken 53253380 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 53028691 times.
✓ Branch 3 taken 224689 times.
53253364 if (field_ptr && *field_ptr) {
7899 53028691 *field_index_ptr = field_ptr - table->field;
7900 53028691 field = *field_ptr;
7901 } else {
7902
6/8
✓ Branch 0 taken 94239 times.
✓ Branch 1 taken 130434 times.
✓ Branch 2 taken 94239 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 94229 times.
✓ Branch 6 taken 224677 times.
✗ Branch 7 not taken.
224683 if (!allow_rowid || my_strcasecmp(system_charset_info, name, "_rowid") ||
7903
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 table->s->rowid_field_offset == 0)
7904 224677 return (Field *)nullptr;
7905 field = table->field[table->s->rowid_field_offset - 1];
7906 }
7907
7908 53028687 return field;
7909 53253364 }
7910
7911 /**
7912 Find field in a table reference.
7913
7914 @param thd thread handler
7915 @param table_list table reference to search
7916 @param name name of field
7917 @param length length of field name
7918 @param item_name name of item if it will be created (VIEW)
7919 @param db_name optional database name that qualifies the field
7920 @param table_name optional table name that qualifies the field
7921 @param[in,out] ref if 'name' is resolved to a view field, ref
7922 is set to point to the found view field
7923 @param want_privilege privileges to check for column
7924 = 0: no privilege checking is needed
7925 @param allow_rowid do allow finding of "_rowid" field?
7926 @param field_index_ptr position in field list (used to
7927 speedup lookup for fields in prepared tables)
7928 @param register_tree_change TRUE if ref is not stack variable and we
7929 need register changes in item tree
7930 @param[out] actual_table the original table reference where the field
7931 belongs - differs from 'table_list' only for
7932 NATURAL_USING joins.
7933
7934 Find a field in a table reference depending on the type of table
7935 reference. There are three types of table references with respect
7936 to the representation of their result columns:
7937 - an array of Field_translator objects for MERGE views and some
7938 information_schema tables,
7939 - an array of Field objects (and possibly a name hash) for stored
7940 tables,
7941 - a list of Natural_join_column objects for NATURAL/USING joins.
7942 This procedure detects the type of the table reference 'table_list'
7943 and calls the corresponding search routine.
7944
7945 The function checks column-level privileges for the found field
7946 according to argument want_privilege.
7947
7948 The function marks the column in corresponding table's read set or
7949 write set according to THD::mark_used_columns.
7950
7951 @retval NULL field is not found
7952 @retval view_ref_found found value in VIEW (real result is in *ref)
7953 @retval otherwise pointer to field
7954 */
7955
7956 187972958 Field *find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
7957 const char *name, size_t length,
7958 const char *item_name, const char *db_name,
7959 const char *table_name, Item **ref,
7960 ulong want_privilege, bool allow_rowid,
7961 uint *field_index_ptr, bool register_tree_change,
7962 TABLE_LIST **actual_table) {
7963 Field *fld;
7964
1/2
✓ Branch 0 taken 187973511 times.
✗ Branch 1 not taken.
187972958 DBUG_TRACE;
7965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187973511 times.
187973511 assert(table_list->alias);
7966
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187973511 times.
187973511 assert(name);
7967
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187973511 times.
187973511 assert(item_name);
7968
5/8
✓ Branch 0 taken 187973370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 187973184 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 946 times.
✓ Branch 5 taken 187972238 times.
✓ Branch 6 taken 1098 times.
✗ Branch 7 not taken.
187973511 DBUG_PRINT("enter", ("table: '%s' field name: '%s' item name: '%s' ref %p",
7969 table_list->alias, name, item_name, ref));
7970
7971 /*
7972 Check that the table and database that qualify the current field name
7973 are the same as the table reference we are going to search for the field.
7974
7975 Exclude from the test below nested joins because the columns in a
7976 nested join generally originate from different tables. Nested joins
7977 also have no table name, except when a nested join is a merge view
7978 or an information schema table.
7979
7980 We include explicitly table references with a 'field_translation' table,
7981 because if there are views over natural joins we don't want to search
7982 inside the view, but we want to search directly in the view columns
7983 which are represented as a 'field_translation'.
7984
7985 TODO: Ensure that table_name, db_name and tables->db always points to
7986 something !
7987 */
7988 187973331 if (/* Exclude nested joins. */
7989 191114180 (!table_list->nested_join ||
7990 /* Include merge views and information schema tables. */
7991
4/4
✓ Branch 0 taken 2925528 times.
✓ Branch 1 taken 215316 times.
✓ Branch 2 taken 160954398 times.
✓ Branch 3 taken 26803622 times.
187973336 table_list->field_translation) &&
7992 /*
7993 Test if the field qualifiers match the table reference we plan
7994 to search.
7995 */
7996
6/6
✓ Branch 0 taken 3140844 times.
✓ Branch 1 taken 184832492 times.
✓ Branch 2 taken 160954397 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 131665855 times.
✓ Branch 5 taken 56307476 times.
536901064 table_name && table_name[0] &&
7997
5/6
✓ Branch 0 taken 160954392 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29288642 times.
✓ Branch 3 taken 131665750 times.
✓ Branch 4 taken 1220110 times.
✓ Branch 5 taken 28068532 times.
160954397 (my_strcasecmp(table_alias_charset, table_list->alias, table_name) ||
7998
6/8
✓ Branch 0 taken 1220110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1220110 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1220106 times.
✓ Branch 5 taken 4 times.
✓ Branch 6 taken 102 times.
✓ Branch 7 taken 1220004 times.
2440216 (db_name && db_name[0] && table_list->db && table_list->db[0] &&
7999 1220106 (table_list->schema_table
8000
3/4
✓ Branch 0 taken 21605 times.
✓ Branch 1 taken 1198501 times.
✓ Branch 2 taken 21605 times.
✗ Branch 3 not taken.
1220106 ? my_strcasecmp(system_charset_info, db_name, table_list->db)
8001 1198501 : strcmp(db_name, table_list->db)))))
8002 131665855 return nullptr;
8003
8004 56307476 *actual_table = nullptr;
8005
8006
2/2
✓ Branch 0 taken 2915600 times.
✓ Branch 1 taken 53391876 times.
56307476 if (table_list->field_translation) {
8007 /* 'table_list' is a view or an information schema table. */
8008
3/4
✓ Branch 0 taken 2915595 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2913150 times.
✓ Branch 3 taken 2445 times.
2915600 if ((fld = find_field_in_view(thd, table_list, name, ref,
8009 register_tree_change)))
8010 2913150 *actual_table = table_list;
8011
2/2
✓ Branch 0 taken 53176594 times.
✓ Branch 1 taken 215282 times.
53391876 } else if (!table_list->nested_join) {
8012 /* 'table_list' is a stored table. */
8013
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 53176594 times.
53176594 assert(table_list->table);
8014
3/4
✓ Branch 0 taken 53176650 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 52952011 times.
✓ Branch 3 taken 224639 times.
53176594 if ((fld = find_field_in_table(table_list->table, name, allow_rowid,
8015 field_index_ptr)))
8016 52952011 *actual_table = table_list;
8017 } else {
8018 /*
8019 'table_list' is a NATURAL/USING join, or an operand of such join that
8020 is a nested join itself.
8021
8022 If the field name we search for is qualified, then search for the field
8023 in the table references used by NATURAL/USING the join.
8024 */
8025
3/4
✓ Branch 0 taken 183417 times.
✓ Branch 1 taken 31865 times.
✓ Branch 2 taken 183417 times.
✗ Branch 3 not taken.
215282 if (table_name && table_name[0]) {
8026
7/12
✓ Branch 0 taken 183417 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 183417 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 328554 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 168718 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 352135 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 328554 times.
✓ Branch 11 taken 23581 times.
352135 for (TABLE_LIST *table : table_list->nested_join->join_list) {
8027
3/4
✓ Branch 0 taken 328554 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 159836 times.
✓ Branch 3 taken 168718 times.
328554 if ((fld = find_field_in_table_ref(
8028 thd, table, name, length, item_name, db_name, table_name, ref,
8029 want_privilege, allow_rowid, field_index_ptr,
8030 register_tree_change, actual_table)))
8031 159836 return fld;
8032 }
8033 23581 return nullptr;
8034 }
8035 /*
8036 Non-qualified field, search directly in the result columns of the
8037 natural join. The condition of the outer IF is true for the top-most
8038 natural join, thus if the field is not qualified, we will search
8039 directly the top-most NATURAL/USING join.
8040 */
8041
1/2
✓ Branch 0 taken 31899 times.
✗ Branch 1 not taken.
31865 fld = find_field_in_natural_join(thd, table_list, name, ref,
8042 register_tree_change, actual_table);
8043 }
8044
8045
2/2
✓ Branch 0 taken 55893195 times.
✓ Branch 1 taken 230949 times.
56124144 if (fld) {
8046 // Check if there are sufficient privileges to the found field.
8047
2/2
✓ Branch 0 taken 14505182 times.
✓ Branch 1 taken 41388013 times.
55893195 if (want_privilege) {
8048
2/2
✓ Branch 0 taken 11917717 times.
✓ Branch 1 taken 2587465 times.
14505182 if (fld != view_ref_found) {
8049
3/4
✓ Branch 0 taken 11917713 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 73 times.
✓ Branch 3 taken 11917640 times.
11917717 if (check_column_grant_in_table_ref(thd, *actual_table, name, length,
8050 want_privilege))
8051 73 return WRONG_GRANT;
8052 } else {
8053
3/6
✓ Branch 0 taken 2587465 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2587465 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2587465 times.
✗ Branch 5 not taken.
2587465 assert(ref && *ref && (*ref)->fixed);
8054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2587464 times.
2587465 assert(*actual_table == (down_cast<Item_ident *>(*ref))->cached_table);
8055
8056 2587464 Column_privilege_tracker tracker(thd, want_privilege);
8057
3/4
✓ Branch 0 taken 2587461 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 72 times.
✓ Branch 3 taken 2587389 times.
2587465 if ((*ref)->walk(&Item::check_column_privileges, enum_walk::PREFIX,
8058 (uchar *)thd))
8059 72 return WRONG_GRANT;
8060
2/2
✓ Branch 0 taken 2587390 times.
✓ Branch 1 taken 72 times.
2587461 }
8061 }
8062
8063 /*
8064 Get read_set correct for this field so that the handler knows that
8065 this field is involved in the query and gets retrieved.
8066 */
8067
2/2
✓ Branch 0 taken 2913089 times.
✓ Branch 1 taken 52979954 times.
55893043 if (fld == view_ref_found) {
8068 2913089 Mark_field mf(thd->mark_used_columns);
8069
1/2
✓ Branch 0 taken 2913092 times.
✗ Branch 1 not taken.
2913089 (*ref)->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
8070 (uchar *)&mf);
8071 } else // surely fld != NULL (see outer if())
8072
1/2
✓ Branch 0 taken 52979931 times.
✗ Branch 1 not taken.
52979954 fld->table->mark_column_used(fld, thd->mark_used_columns);
8073 }
8074 56123972 return fld;
8075 187973389 }
8076
8077 /*
8078 Find field in table, no side effects, only purpose is to check for field
8079 in table object and get reference to the field if found.
8080
8081 SYNOPSIS
8082 find_field_in_table_sef()
8083
8084 table table where to find
8085 name Name of field searched for
8086
8087 RETURN
8088 0 field is not found
8089 # pointer to field
8090 */
8091
8092 8532 Field *find_field_in_table_sef(TABLE *table, const char *name) {
8093 8532 Field **field_ptr = nullptr;
8094
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8532 times.
8532 if (!(field_ptr = table->field)) return nullptr;
8095
2/2
✓ Branch 0 taken 12697 times.
✓ Branch 1 taken 9 times.
12706 for (; *field_ptr; ++field_ptr) {
8096 // NOTE: See comment on the same call in find_field_in_table().
8097
2/2
✓ Branch 0 taken 8523 times.
✓ Branch 1 taken 4174 times.
12697 if (!my_strcasecmp(system_charset_info, (*field_ptr)->field_name, name))
8098 8523 break;
8099 }
8100
1/2
✓ Branch 0 taken 8532 times.
✗ Branch 1 not taken.
8532 if (field_ptr)
8101 8532 return *field_ptr;
8102 else
8103 return (Field *)nullptr;
8104 }
8105
8106 /*
8107 Find field in table list.
8108
8109 SYNOPSIS
8110 find_field_in_tables()
8111 thd pointer to current thread structure
8112 item field item that should be found
8113 first_table list of tables to be searched for item
8114 last_table end of the list of tables to search for item. If NULL
8115 then search to the end of the list 'first_table'.
8116 ref if 'item' is resolved to a view field, ref is set to
8117 point to the found view field
8118 report_error Degree of error reporting:
8119 - IGNORE_ERRORS then do not report any error
8120 - IGNORE_EXCEPT_NON_UNIQUE report only non-unique
8121 fields, suppress all other errors
8122 - REPORT_EXCEPT_NON_UNIQUE report all other errors
8123 except when non-unique fields were found
8124 - REPORT_ALL_ERRORS
8125 want_privilege column privileges to check
8126 = 0: no need to check privileges
8127 register_tree_change true if ref is not a stack variable and we
8128 to need register changes in item tree
8129
8130 RETURN VALUES
8131 0 If error: the found field is not unique, or there are
8132 no sufficient access privileges for the found field,
8133 or the field is qualified with non-existing table.
8134 not_found_field The function was called with report_error ==
8135 (IGNORE_ERRORS || IGNORE_EXCEPT_NON_UNIQUE) and a
8136 field was not found.
8137 view_ref_found View field is found, item passed through ref parameter
8138 found field If a item was resolved to some field
8139 */
8140
8141 56005389 Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *first_table,
8142 TABLE_LIST *last_table, Item **ref,
8143 find_item_error_report_type report_error,
8144 ulong want_privilege, bool register_tree_change) {
8145 56005389 Field *found = nullptr;
8146 56005389 const char *db = item->db_name;
8147 56005389 const char *table_name = item->table_name;
8148 56005389 const char *name = item->field_name;
8149 56005389 size_t length = strlen(name);
8150 uint field_index;
8151 char name_buff[NAME_LEN + 1];
8152 TABLE_LIST *actual_table;
8153 bool allow_rowid;
8154
8155
4/4
✓ Branch 0 taken 29321800 times.
✓ Branch 1 taken 26683589 times.
✓ Branch 2 taken 96 times.
✓ Branch 3 taken 29321704 times.
56005389 if (!table_name || !table_name[0]) {
8156 26683685 table_name = nullptr; // For easier test
8157 26683685 db = nullptr;
8158 }
8159
8160
6/6
✓ Branch 0 taken 26683691 times.
✓ Branch 1 taken 29321698 times.
✓ Branch 2 taken 26681807 times.
✓ Branch 3 taken 1884 times.
✓ Branch 4 taken 26558582 times.
✓ Branch 5 taken 123225 times.
56005389 allow_rowid = table_name || (first_table && !first_table->next_local);
8161
8162
2/2
✓ Branch 0 taken 14327 times.
✓ Branch 1 taken 55991062 times.
56005389 if (item->cached_table) {
8163 /*
8164 This shortcut is used by prepared statements. We assume that
8165 TABLE_LIST *first_table is not changed during query execution (which
8166 is true for all queries except RENAME but luckily RENAME doesn't
8167 use fields...) so we can rely on reusing pointer to its member.
8168 With this optimization we also miss case when addition of one more
8169 field makes some prepared query ambiguous and so erroneous, but we
8170 accept this trade off.
8171 */
8172 14327 TABLE_LIST *table_ref = item->cached_table;
8173
8174 /*
8175 @todo WL#6570 - is this reasonable???
8176 Also refactor this code to replace "cached_table" with "table_ref" -
8177 as there is no longer need for more than one resolving, hence
8178 no "caching" as well.
8179 */
8180
3/4
✓ Branch 0 taken 14327 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14323 times.
✓ Branch 3 taken 4 times.
14327 if (item->type() == Item::FIELD_ITEM)
8181 14323 field_index = down_cast<Item_field *>(item)->field_index;
8182
8183 /*
8184 The condition (table_ref->view == NULL) ensures that we will call
8185 find_field_in_table even in the case of information schema tables
8186 when table_ref->field_translation != NULL.
8187 */
8188
8189
6/6
✓ Branch 0 taken 14251 times.
✓ Branch 1 taken 76 times.
✓ Branch 2 taken 5449 times.
✓ Branch 3 taken 8802 times.
✓ Branch 4 taken 5449 times.
✓ Branch 5 taken 8878 times.
14327 if (table_ref->table && !table_ref->is_view()) {
8190
1/2
✓ Branch 0 taken 5449 times.
✗ Branch 1 not taken.
5449 found = find_field_in_table(table_ref->table, name, true, &field_index);
8191 // Check if there are sufficient privileges to the found field.
8192
3/6
✓ Branch 0 taken 5449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5449 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5449 times.
10898 if (found && want_privilege &&
8193
2/4
✓ Branch 0 taken 5449 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5449 times.
5449 check_column_grant_in_table_ref(thd, table_ref, name, length,
8194 want_privilege))
8195 found = WRONG_GRANT;
8196
2/4
✓ Branch 0 taken 5449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5449 times.
✗ Branch 3 not taken.
5449 if (found && found != WRONG_GRANT)
8197
1/2
✓ Branch 0 taken 5475 times.
✗ Branch 1 not taken.
5449 table_ref->table->mark_column_used(found, thd->mark_used_columns);
8198 } else {
8199
1/2
✓ Branch 0 taken 8878 times.
✗ Branch 1 not taken.
8878 found = find_field_in_table_ref(thd, table_ref, name, length,
8200 item->item_name.ptr(), nullptr, nullptr,
8201 ref, want_privilege, true, &field_index,
8202 register_tree_change, &actual_table);
8203 }
8204
2/2
✓ Branch 0 taken 14327 times.
✓ Branch 1 taken 26 times.
14353 if (found) {
8205
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14327 times.
14327 if (found == WRONG_GRANT) return nullptr;
8206
8207 // @todo WL#6570 move this assignment to a more strategic place?
8208
3/4
✓ Branch 0 taken 14327 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14323 times.
✓ Branch 3 taken 4 times.
14327 if (item->type() == Item::FIELD_ITEM)
8209 14323 down_cast<Item_field *>(item)->field_index = field_index;
8210
8211 14327 return found;
8212 }
8213 }
8214
8215
9/10
✓ Branch 0 taken 1220252 times.
✓ Branch 1 taken 54770836 times.
✓ Branch 2 taken 1140580 times.
✓ Branch 3 taken 79672 times.
✓ Branch 4 taken 1140580 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 47847 times.
✓ Branch 7 taken 1092733 times.
✓ Branch 8 taken 127519 times.
✓ Branch 9 taken 55863569 times.
55991088 if (db && (lower_case_table_names || is_infoschema_db(db, strlen(db)))) {
8216 /*
8217 convert database to lower case for comparison.
8218 We can't do this in Item_field as this would change the
8219 'name' of the item which may be used in the select list
8220
8221 The 'information_schema' name is treated as case-insensitive
8222 identifier when specified in FROM clause even in
8223 lower_case_table_names=0. We lowercase the 'information_schema' name
8224 below to treat it as case-insensitive even when it is referred in WHERE
8225 or SELECT clause.
8226 */
8227
1/2
✓ Branch 0 taken 127519 times.
✗ Branch 1 not taken.
127519 strmake(name_buff, db, sizeof(name_buff) - 1);
8228
1/2
✓ Branch 0 taken 127519 times.
✗ Branch 1 not taken.
127519 my_casedn_str(files_charset_info, name_buff);
8229 127519 db = name_buff;
8230 }
8231
8232
4/4
✓ Branch 0 taken 55988508 times.
✓ Branch 1 taken 2580 times.
✓ Branch 2 taken 55913064 times.
✓ Branch 3 taken 75444 times.
55991088 if (first_table && first_table->query_block &&
8233
2/2
✓ Branch 0 taken 3783 times.
✓ Branch 1 taken 55909281 times.
55913064 first_table->query_block->end_lateral_table)
8234 3783 last_table = first_table->query_block->end_lateral_table;
8235
2/2
✓ Branch 0 taken 3982014 times.
✓ Branch 1 taken 52005291 times.
55987305 else if (last_table)
8236 3982014 last_table = last_table->next_name_resolution_table;
8237
8238 TABLE_LIST *cur_table;
8239
8240
2/2
✓ Branch 0 taken 187635085 times.
✓ Branch 1 taken 54770281 times.
242405366 for (cur_table = first_table; cur_table != last_table;
8241 186414278 cur_table = cur_table->next_name_resolution_table) {
8242
1/2
✓ Branch 0 taken 187635622 times.
✗ Branch 1 not taken.
187635085 Field *cur_field = find_field_in_table_ref(
8243 thd, cur_table, name, length, item->item_name.ptr(), db, table_name,
8244 ref, want_privilege, allow_rowid, &field_index, register_tree_change,
8245 &actual_table);
8246
9/10
✓ Branch 0 taken 131751771 times.
✓ Branch 1 taken 55883851 times.
✓ Branch 2 taken 131751747 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 131751740 times.
✓ Branch 5 taken 7 times.
✓ Branch 6 taken 144 times.
✓ Branch 7 taken 187635447 times.
✓ Branch 8 taken 151 times.
✓ Branch 9 taken 187635447 times.
187635622 if ((cur_field == nullptr && thd->is_error()) || cur_field == WRONG_GRANT)
8247 151 return nullptr;
8248
8249
2/2
✓ Branch 0 taken 55883810 times.
✓ Branch 1 taken 131751637 times.
187635447 if (cur_field) {
8250 /*
8251 Store the original table of the field, which may be different from
8252 cur_table in the case of NATURAL/USING join.
8253 */
8254 55883810 item->cached_table =
8255
4/4
✓ Branch 0 taken 55777416 times.
✓ Branch 1 taken 106394 times.
✓ Branch 2 taken 55775811 times.
✓ Branch 3 taken 1605 times.
55883810 (!actual_table->cacheable_table || found) ? nullptr : actual_table;
8256
8257 // @todo WL#6570 move this assignment to a more strategic place?
8258
3/4
✓ Branch 0 taken 55883763 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 55883661 times.
✓ Branch 3 taken 102 times.
55883810 if (item->type() == Item::FIELD_ITEM)
8259 55883661 down_cast<Item_field *>(item)->field_index = field_index;
8260
8261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 55883760 times.
55883760 assert(thd->where);
8262 /*
8263 If we found a fully qualified field we return it directly as it can't
8264 have duplicates.
8265 */
8266
2/2
✓ Branch 0 taken 1219514 times.
✓ Branch 1 taken 54664246 times.
55883760 if (db) return cur_field;
8267
8268
2/2
✓ Branch 0 taken 1605 times.
✓ Branch 1 taken 54662641 times.
54664246 if (found) {
8269
3/4
✓ Branch 0 taken 1605 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 1585 times.
1605 if (report_error == REPORT_ALL_ERRORS ||
8270 report_error == IGNORE_EXCEPT_NON_UNIQUE)
8271
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
21 my_error(ER_NON_UNIQ_ERROR, MYF(0),
8272
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 table_name ? item->full_name() : name, thd->where);
8273 1605 return (Field *)nullptr;
8274 }
8275 54662641 found = cur_field;
8276 }
8277 }
8278
8279
2/2
✓ Branch 0 taken 54661051 times.
✓ Branch 1 taken 109230 times.
54770281 if (found) return found;
8280
8281 /*
8282 If the field was qualified and there were no tables to search, issue
8283 an error that an unknown table was given. The situation is detected
8284 as follows: if there were no tables we wouldn't go through the loop
8285 and cur_table wouldn't be updated by the loop increment part, so it
8286 will be equal to the first table.
8287 @todo revisit this logic. If the first table is a table function or lateral
8288 derived table and contains an inner column reference in it which is not
8289 found, cur_table==first_table, even though there _were_ tables to search.
8290 */
8291
6/6
✓ Branch 0 taken 19580 times.
✓ Branch 1 taken 89650 times.
✓ Branch 2 taken 728 times.
✓ Branch 3 taken 18852 times.
✓ Branch 4 taken 480 times.
✓ Branch 5 taken 248 times.
109230 if (table_name && (cur_table == first_table) &&
8292
2/2
✓ Branch 0 taken 396 times.
✓ Branch 1 taken 84 times.
480 (report_error == REPORT_ALL_ERRORS ||
8293 report_error == REPORT_EXCEPT_NON_UNIQUE)) {
8294 char buff[NAME_LEN * 2 + 2];
8295
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 644 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
644 if (db && db[0]) {
8296 strxnmov(buff, sizeof(buff) - 1, db, ".", table_name, NullS);
8297 table_name = buff;
8298 }
8299
1/2
✓ Branch 0 taken 248 times.
✗ Branch 1 not taken.
644 my_error(ER_UNKNOWN_TABLE, MYF(0), table_name, thd->where);
8300 248 } else {
8301
3/4
✓ Branch 0 taken 106930 times.
✓ Branch 1 taken 1656 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 106930 times.
108586 if (report_error == REPORT_ALL_ERRORS ||
8302 report_error == REPORT_EXCEPT_NON_UNIQUE) {
8303 /* We now know that this column does not exist in any table_list
8304 of the query. If user does not have grant, then we should throw
8305 error stating 'access denied'. If user does have right then we can
8306 give proper error like column does not exist. Following is check
8307 to see if column has wrong grants and avoids error like 'bad field'
8308 and throw column access error.
8309 */
8310
6/6
✓ Branch 0 taken 1277 times.
✓ Branch 1 taken 379 times.
✓ Branch 2 taken 1147 times.
✓ Branch 3 taken 130 times.
✓ Branch 4 taken 1655 times.
✓ Branch 5 taken 1 times.
2803 if (!first_table || (want_privilege == 0) ||
8311
3/4
✓ Branch 0 taken 1147 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1146 times.
✓ Branch 3 taken 1 times.
1147 !check_column_grant_in_table_ref(thd, first_table, name, length,
8312 want_privilege))
8313
2/4
✓ Branch 0 taken 1655 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1655 times.
✗ Branch 3 not taken.
1655 my_error(ER_BAD_FIELD_ERROR, MYF(0), item->full_name(), thd->where);
8314 } else
8315 106930 found = not_found_field;
8316 }
8317 108834 return found;
8318 }
8319
8320 /*
8321 Find Item in list of items (find_field_in_tables analog)
8322
8323 TODO
8324 is it better return only counter?
8325
8326 SYNOPSIS
8327 find_item_in_list()
8328 find Item to find
8329 items List of items
8330 counter To return number of found item
8331 report_error
8332 REPORT_ALL_ERRORS report errors, return 0 if error
8333 REPORT_EXCEPT_NOT_FOUND Do not report 'not found' error and
8334 return not_found_item, report other errors,
8335 return 0
8336 IGNORE_ERRORS Do not report errors, return 0 if error
8337 resolution Set to the resolution type if the item is found
8338 (it says whether the item is resolved
8339 against an alias name,
8340 or as a field name without alias,
8341 or as a field hidden by alias,
8342 or ignoring alias)
8343
8344 RETURN VALUES
8345 0 Item is not found or item is not unique,
8346 error message is reported
8347 not_found_item Function was called with
8348 report_error == REPORT_EXCEPT_NOT_FOUND and
8349 item was not found. No error message was reported
8350 found field
8351 */
8352
8353 /* Special Item pointer to serve as a return value from find_item_in_list(). */
8354 Item **not_found_item = (Item **)0x1;
8355
8356 1168376 Item **find_item_in_list(THD *thd, Item *find, mem_root_deque<Item *> *items,
8357 uint *counter,
8358 find_item_error_report_type report_error,
8359 enum_resolution_type *resolution) {
8360 1168376 Item **found = nullptr, **found_unaliased = nullptr;
8361 1168376 const char *db_name = nullptr;
8362 1168376 const char *field_name = nullptr;
8363 1168376 const char *table_name = nullptr;
8364 1168376 bool found_unaliased_non_uniq = false;
8365 /*
8366 true if the item that we search for is a valid name reference
8367 (and not an item that happens to have a name).
8368 */
8369 1168376 bool is_ref_by_name = false;
8370 1168376 uint unaliased_counter = 0;
8371
8372 1168376 *resolution = NOT_RESOLVED;
8373
8374 1168376 is_ref_by_name =
8375
4/4
✓ Branch 0 taken 114052 times.
✓ Branch 1 taken 1054324 times.
✓ Branch 2 taken 17384 times.
✓ Branch 3 taken 96668 times.
1168376 (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM);
8376
2/2
✓ Branch 0 taken 1071708 times.
✓ Branch 1 taken 96668 times.
1168376 if (is_ref_by_name) {
8377 1071708 field_name = ((Item_ident *)find)->field_name;
8378 1071708 table_name = ((Item_ident *)find)->table_name;
8379 1071708 db_name = ((Item_ident *)find)->db_name;
8380 }
8381
8382 1168376 int i = 0;
8383
2/4
✓ Branch 0 taken 1168376 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1168376 times.
✗ Branch 3 not taken.
1168376 for (auto it = VisibleFields(*items).begin();
8384
6/10
✓ Branch 0 taken 10201691 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 11370066 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11370065 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 11370065 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 10472753 times.
✓ Branch 9 taken 897312 times.
11370067 it != VisibleFields(*items).end(); ++it, ++i) {
8385
1/2
✓ Branch 0 taken 10472753 times.
✗ Branch 1 not taken.
10472753 Item *item = *it;
8386
8/10
✓ Branch 0 taken 10066588 times.
✓ Branch 1 taken 406165 times.
✓ Branch 2 taken 10066589 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10066589 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7879229 times.
✓ Branch 7 taken 2187360 times.
✓ Branch 8 taken 7879229 times.
✓ Branch 9 taken 2593525 times.
10472753 if (field_name && item->real_item()->type() == Item::FIELD_ITEM) {
8387 7879229 Item_ident *item_field = (Item_ident *)item;
8388
8389 /*
8390 In case of group_concat() with ORDER BY condition in the QUERY
8391 item_field can be field of temporary table without item name
8392 (if this field created from expression argument of group_concat()),
8393 => we have to check presence of name before compare
8394 */
8395
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7879229 times.
7879229 if (!item_field->item_name.is_set()) continue;
8396
8397
2/2
✓ Branch 0 taken 561364 times.
✓ Branch 1 taken 7317865 times.
7879229 if (table_name) {
8398 /*
8399 If table name is specified we should find field 'field_name' in
8400 table 'table_name'. According to SQL-standard we should ignore
8401 aliases in this case.
8402
8403 Since we should NOT prefer fields from the select list over
8404 other fields from the tables participating in this select in
8405 case of ambiguity we have to do extra check outside this function.
8406
8407 We use strcmp for table names and database names as these may be
8408 case sensitive. In cases where they are not case sensitive, they
8409 are always in lower case.
8410
8411 item_field->field_name and item_field->table_name can be 0x0 if
8412 item is not fix_field()'ed yet.
8413 */
8414
1/2
✓ Branch 0 taken 561364 times.
✗ Branch 1 not taken.
561364 if (item_field->field_name && item_field->table_name &&
8415
3/4
✓ Branch 0 taken 561364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44046 times.
✓ Branch 3 taken 517318 times.
561364 !my_strcasecmp(system_charset_info, item_field->field_name,
8416 44046 field_name) &&
8417
3/4
✓ Branch 0 taken 44046 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 39351 times.
✓ Branch 3 taken 4695 times.
44046 !my_strcasecmp(table_alias_charset, item_field->table_name,
8418
5/6
✓ Branch 0 taken 561364 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15729 times.
✓ Branch 3 taken 23622 times.
✓ Branch 4 taken 39351 times.
✓ Branch 5 taken 522013 times.
1138457 table_name) &&
8419 15729 (!db_name ||
8420
2/4
✓ Branch 0 taken 15729 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15729 times.
✗ Branch 3 not taken.
15729 (item_field->db_name && !strcmp(item_field->db_name, db_name)))) {
8421
2/2
✓ Branch 0 taken 100 times.
✓ Branch 1 taken 39251 times.
39351 if (found_unaliased) {
8422
2/4
✓ Branch 0 taken 100 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 100 times.
✗ Branch 3 not taken.
100 if ((*found_unaliased)->eq(item, false)) continue;
8423 /*
8424 Two matching fields in select list.
8425 We already can bail out because we are searching through
8426 unaliased names only and will have duplicate error anyway.
8427 */
8428 if (report_error != IGNORE_ERRORS)
8429 my_error(ER_NON_UNIQ_ERROR, MYF(0), find->full_name(),
8430 thd->where);
8431 12 return (Item **)nullptr;
8432 }
8433
1/2
✓ Branch 0 taken 39251 times.
✗ Branch 1 not taken.
39251 found_unaliased = &*it;
8434 39251 unaliased_counter = i;
8435 39251 *resolution = RESOLVED_IGNORING_ALIAS;
8436
2/2
✓ Branch 0 taken 15729 times.
✓ Branch 1 taken 23522 times.
39251 if (db_name) break; // Perfect match
8437 }
8438 } else {
8439
1/2
✓ Branch 0 taken 7317865 times.
✗ Branch 1 not taken.
7317865 int fname_cmp = my_strcasecmp(system_charset_info,
8440 item_field->field_name, field_name);
8441
3/4
✓ Branch 0 taken 7317865 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 719483 times.
✓ Branch 3 taken 6598382 times.
7317865 if (item_field->item_name.eq_safe(field_name)) {
8442 /*
8443 If table name was not given we should scan through aliases
8444 and non-aliased fields first. We are also checking unaliased
8445 name of the field in then next else-if, to be able to find
8446 instantly field (hidden by alias) if no suitable alias or
8447 non-aliased field was found.
8448 */
8449
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 718859 times.
719483 if (found) {
8450
3/4
✓ Branch 0 taken 624 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 612 times.
✓ Branch 3 taken 12 times.
624 if ((*found)->eq(item, false)) continue; // Same field twice
8451
1/2
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
12 if (report_error != IGNORE_ERRORS)
8452
2/4
✓ Branch 0 taken 12 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12 times.
✗ Branch 3 not taken.
12 my_error(ER_NON_UNIQ_ERROR, MYF(0), find->full_name(),
8453 thd->where);
8454 12 return (Item **)nullptr;
8455 }
8456
1/2
✓ Branch 0 taken 718859 times.
✗ Branch 1 not taken.
718859 found = &*it;
8457 718859 *counter = i;
8458 718859 *resolution =
8459
2/2
✓ Branch 0 taken 1255 times.
✓ Branch 1 taken 717604 times.
718859 fname_cmp ? RESOLVED_AGAINST_ALIAS : RESOLVED_WITH_NO_ALIAS;
8460
2/2
✓ Branch 0 taken 35270 times.
✓ Branch 1 taken 6563112 times.
6598382 } else if (!fname_cmp) {
8461 /*
8462 We will use non-aliased field or react on such ambiguities only if
8463 we won't be able to find aliased field.
8464 Again if we have ambiguity with field outside of select list
8465 we should prefer fields from select list.
8466 */
8467
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 35264 times.
35270 if (found_unaliased) {
8468
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
6 if ((*found_unaliased)->eq(item, false))
8469 continue; // Same field twice
8470 6 found_unaliased_non_uniq = true;
8471 }
8472
1/2
✓ Branch 0 taken 35270 times.
✗ Branch 1 not taken.
35270 found_unaliased = &*it;
8473 35270 unaliased_counter = i;
8474 }
8475 }
8476
2/2
✓ Branch 0 taken 2345819 times.
✓ Branch 1 taken 247706 times.
2593525 } else if (!table_name) {
8477
7/8
✓ Branch 0 taken 1939697 times.
✓ Branch 1 taken 406122 times.
✓ Branch 2 taken 1939697 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 197906 times.
✓ Branch 5 taken 1741791 times.
✓ Branch 6 taken 197906 times.
✓ Branch 7 taken 2147913 times.
2345819 if (is_ref_by_name && item->item_name.eq_safe(find->item_name)) {
8478
1/2
✓ Branch 0 taken 197906 times.
✗ Branch 1 not taken.
197906 found = &*it;
8479 197906 *counter = i;
8480 197906 *resolution = RESOLVED_AGAINST_ALIAS;
8481 197906 break;
8482
3/4
✓ Branch 0 taken 2147913 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 57369 times.
✓ Branch 3 taken 2090544 times.
2147913 } else if (find->eq(item, false)) {
8483
1/2
✓ Branch 0 taken 57369 times.
✗ Branch 1 not taken.
57369 found = &*it;
8484 57369 *counter = i;
8485 57369 *resolution = RESOLVED_IGNORING_ALIAS;
8486 57369 break;
8487 }
8488
6/8
✓ Branch 0 taken 247707 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 247707 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14121 times.
✓ Branch 5 taken 233586 times.
✓ Branch 6 taken 14085 times.
✓ Branch 7 taken 233621 times.
261827 } else if (table_name && item->type() == Item::REF_ITEM &&
8489
3/4
✓ Branch 0 taken 14121 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14085 times.
✓ Branch 3 taken 36 times.
14121 ((Item_ref *)item)->ref_type() == Item_ref::VIEW_REF) {
8490 /*
8491 TODO:Here we process prefixed view references only. What we should
8492 really do is process all types of Item_refs. But this will currently
8493 lead to a clash with the way references to outer SELECTs (from the
8494 HAVING clause) are handled in e.g. :
8495 SELECT 1 FROM t1 AS t1_o GROUP BY a
8496 HAVING (SELECT t1_o.a FROM t1 AS t1_i GROUP BY t1_i.a LIMIT 1).
8497 Processing all Item_refs here will cause t1_o.a to resolve to itself.
8498 We still need to process the special case of Item_view_ref
8499 because in the context of views they have the same meaning as
8500 Item_field for tables.
8501 */
8502 14085 Item_ident *item_ref = (Item_ident *)item;
8503
2/4
✓ Branch 0 taken 14085 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 49 times.
✗ Branch 3 not taken.
14134 if (item_ref->item_name.eq_safe(field_name) && item_ref->table_name &&
8504
3/4
✓ Branch 0 taken 49 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 47 times.
✓ Branch 3 taken 2 times.
49 !my_strcasecmp(table_alias_charset, item_ref->table_name,
8505
6/6
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 14036 times.
✓ Branch 2 taken 13 times.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 47 times.
✓ Branch 5 taken 14038 times.
14147 table_name) &&
8506 13 (!db_name ||
8507
2/4
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13 times.
✗ Branch 3 not taken.
13 (item_ref->db_name && !strcmp(item_ref->db_name, db_name)))) {
8508
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 found = &*it;
8509 47 *counter = i;
8510 47 *resolution = RESOLVED_IGNORING_ALIAS;
8511 47 break;
8512 }
8513 }
8514 }
8515
2/2
✓ Branch 0 taken 194206 times.
✓ Branch 1 taken 974157 times.
1168363 if (!found) {
8516
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 194200 times.
194206 if (found_unaliased_non_uniq) {
8517
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (report_error != IGNORE_ERRORS)
8518 6 my_error(ER_NON_UNIQ_ERROR, MYF(0), find->full_name(), thd->where);
8519 6 return (Item **)nullptr;
8520 }
8521
2/2
✓ Branch 0 taken 74497 times.
✓ Branch 1 taken 119703 times.
194200 if (found_unaliased) {
8522 74497 found = found_unaliased;
8523 74497 *counter = unaliased_counter;
8524 74497 *resolution = RESOLVED_BEHIND_ALIAS;
8525 }
8526 }
8527
2/2
✓ Branch 0 taken 1048655 times.
✓ Branch 1 taken 119702 times.
1168357 if (found) return found;
8528
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 119702 times.
119702 if (report_error != REPORT_EXCEPT_NOT_FOUND) {
8529 if (report_error == REPORT_ALL_ERRORS)
8530 my_error(ER_BAD_FIELD_ERROR, MYF(0), find->full_name(), thd->where);
8531 return (Item **)nullptr;
8532 } else
8533 119702 return not_found_item;
8534 }
8535
8536 /*
8537 Test if a string is a member of a list of strings.
8538
8539 SYNOPSIS
8540 test_if_string_in_list()
8541 find the string to look for
8542 str_list a list of strings to be searched
8543
8544 DESCRIPTION
8545 Sequentially search a list of strings for a string, and test whether
8546 the list contains the same string.
8547
8548 RETURN
8549 true if find is in str_list
8550 false otherwise
8551 */
8552
8553 299982 static bool test_if_string_in_list(const char *find, List<String> *str_list) {
8554
1/2
✓ Branch 0 taken 299982 times.
✗ Branch 1 not taken.
299982 List_iterator<String> str_list_it(*str_list);
8555 String *curr_str;
8556 299982 size_t find_length = strlen(find);
8557
2/2
✓ Branch 0 taken 318819 times.
✓ Branch 1 taken 287208 times.
606027 while ((curr_str = str_list_it++)) {
8558
2/2
✓ Branch 0 taken 282287 times.
✓ Branch 1 taken 36532 times.
318819 if (find_length != curr_str->length()) continue;
8559
3/4
✓ Branch 0 taken 36532 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12774 times.
✓ Branch 3 taken 23758 times.
36532 if (!my_strcasecmp(system_charset_info, find, curr_str->ptr())) return true;
8560 }
8561 287208 return false;
8562 }
8563
8564 /*
8565 Create a new name resolution context for an item so that it is
8566 being resolved in a specific table reference.
8567
8568 SYNOPSIS
8569 set_new_item_local_context()
8570 thd pointer to current thread
8571 item item for which new context is created and set
8572 table_ref table ref where an item showld be resolved
8573
8574 DESCRIPTION
8575 Create a new name resolution context for an item, so that the item
8576 is resolved only the supplied 'table_ref'.
8577
8578 RETURN
8579 false if all OK
8580 true otherwise
8581 */
8582
8583 29798 static bool set_new_item_local_context(THD *thd, Item_ident *item,
8584 TABLE_LIST *table_ref) {
8585 Name_resolution_context *context;
8586
3/6
✓ Branch 0 taken 29798 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 29798 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 29798 times.
29798 if (!(context = new (thd->mem_root) Name_resolution_context))
8587 return true; /* purecov: inspected */
8588 29798 context->init();
8589 29798 context->first_name_resolution_table = context->last_name_resolution_table =
8590 table_ref;
8591 29798 context->query_block = table_ref->query_block;
8592 29798 context->next_context = table_ref->query_block->first_context;
8593 29798 table_ref->query_block->first_context = context;
8594 29798 item->context = context;
8595 29798 return false;
8596 }
8597
8598 /*
8599 Find and mark the common columns of two table references.
8600
8601 SYNOPSIS
8602 mark_common_columns()
8603 thd [in] current thread
8604 table_ref_1 [in] the first (left) join operand
8605 table_ref_2 [in] the second (right) join operand
8606 using_fields [in] if the join is JOIN...USING - the join columns,
8607 if NATURAL join, then NULL
8608 found_using_fields [out] number of fields from the USING clause that were
8609 found among the common fields
8610
8611 DESCRIPTION
8612 The procedure finds the common columns of two relations (either
8613 tables or intermediate join results), and adds an equi-join condition
8614 to the ON clause of 'table_ref_2' for each pair of matching columns.
8615 If some of table_ref_XXX represents a base table or view, then we
8616 create new 'Natural_join_column' instances for each column
8617 reference and store them in the 'join_columns' of the table
8618 reference.
8619
8620 IMPLEMENTATION
8621 The procedure assumes that store_natural_using_join_columns() was
8622 called for the previous level of NATURAL/USING joins.
8623
8624 RETURN
8625 true error when some common column is non-unique, or out of memory
8626 false OK
8627 */
8628
8629 13499 static bool mark_common_columns(THD *thd, TABLE_LIST *table_ref_1,
8630 TABLE_LIST *table_ref_2,
8631 List<String> *using_fields,
8632 uint *found_using_fields) {
8633
2/4
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13499 times.
✗ Branch 3 not taken.
13499 Field_iterator_table_ref it_1, it_2;
8634 Natural_join_column *nj_col_1, *nj_col_2;
8635 13499 bool first_outer_loop = true;
8636 13499 List<Field> fields;
8637 /*
8638 Leaf table references to which new natural join columns are added
8639 if the leaves are != NULL.
8640 */
8641 13499 TABLE_LIST *leaf_1 =
8642
4/4
✓ Branch 0 taken 3427 times.
✓ Branch 1 taken 10072 times.
✓ Branch 2 taken 3249 times.
✓ Branch 3 taken 178 times.
13499 (table_ref_1->nested_join && !table_ref_1->is_natural_join) ? nullptr
8643 : table_ref_1;
8644 13499 TABLE_LIST *leaf_2 =
8645
4/4
✓ Branch 0 taken 1233 times.
✓ Branch 1 taken 12266 times.
✓ Branch 2 taken 518 times.
✓ Branch 3 taken 715 times.
13499 (table_ref_2->nested_join && !table_ref_2->is_natural_join) ? nullptr
8646 : table_ref_2;
8647
8648
1/2
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
13499 DBUG_TRACE;
8649
3/8
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13499 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 13499 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
13499 DBUG_PRINT("info", ("operand_1: %s operand_2: %s", table_ref_1->alias,
8650 table_ref_2->alias));
8651
8652 /*
8653 Hidden columns for functional indexes don't participate in NATURAL /
8654 USING JOIN and invisible columns don't participate in NATURAL JOIN.
8655 (we need to go through get_or_create_column_ref() before calling
8656 this method).
8657 */
8658 11556913 auto is_non_participant_column = [using_fields](Field *field) {
8659
3/4
✓ Branch 0 taken 5757831 times.
✓ Branch 1 taken 41251 times.
✓ Branch 2 taken 5757831 times.
✗ Branch 3 not taken.
17314744 return (field != nullptr &&
8660
2/2
✓ Branch 0 taken 9265 times.
✓ Branch 1 taken 5748566 times.
11515662 (field->is_field_for_functional_index() ||
8661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9265 times.
5808347 ((using_fields == nullptr) && field->is_hidden_by_user())));
8662 13499 };
8663
8664
1/2
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
13499 Prepared_stmt_arena_holder ps_arena_holder(thd);
8665
8666 13499 *found_using_fields = 0;
8667
8668
5/8
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 302145 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 315644 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 302195 times.
✓ Branch 7 taken 13449 times.
315644 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) {
8669 302195 bool found = false;
8670 const char *field_name_1;
8671 /* true if field_name_1 is a member of using_fields */
8672 bool is_using_column_1;
8673
2/4
✓ Branch 0 taken 302195 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 302195 times.
302195 if (!(nj_col_1 = it_1.get_or_create_column_ref(thd, leaf_1))) return true;
8674
2/4
✓ Branch 0 taken 302195 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 302195 times.
302195 if (is_non_participant_column(it_1.field())) continue;
8675
8676
1/2
✓ Branch 0 taken 302195 times.
✗ Branch 1 not taken.
302195 field_name_1 = nj_col_1->name();
8677 302195 is_using_column_1 =
8678
5/6
✓ Branch 0 taken 299088 times.
✓ Branch 1 taken 3107 times.
✓ Branch 2 taken 299088 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12218 times.
✓ Branch 5 taken 286870 times.
302195 using_fields && test_if_string_in_list(field_name_1, using_fields);
8679
3/14
✓ Branch 0 taken 302195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 302195 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 302195 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
302195 DBUG_PRINT("info", ("field_name_1=%s.%s",
8680 nj_col_1->table_name() ? nj_col_1->table_name() : "",
8681 field_name_1));
8682
8683 /*
8684 Find a field with the same name in table_ref_2.
8685
8686 Note that for the second loop, it_2.set() will iterate over
8687 table_ref_2->join_columns and not generate any new elements or
8688 lists.
8689 */
8690 302195 nj_col_2 = nullptr;
8691
5/8
✓ Branch 0 taken 302195 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5496837 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5799032 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5496887 times.
✓ Branch 7 taken 302145 times.
5799032 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) {
8692 Natural_join_column *cur_nj_col_2;
8693 const char *cur_field_name_2;
8694
2/4
✓ Branch 0 taken 5496887 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5496887 times.
5496887 if (!(cur_nj_col_2 = it_2.get_or_create_column_ref(thd, leaf_2)))
8695 return true;
8696
2/4
✓ Branch 0 taken 5496887 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 5496887 times.
5496887 if (is_non_participant_column(it_2.field())) continue;
8697
8698
1/2
✓ Branch 0 taken 5496887 times.
✗ Branch 1 not taken.
5496887 cur_field_name_2 = cur_nj_col_2->name();
8699
3/14
✓ Branch 0 taken 5496887 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5496887 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5496887 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
5496887 DBUG_PRINT("info",
8700 ("cur_field_name_2=%s.%s",
8701 cur_nj_col_2->table_name() ? cur_nj_col_2->table_name() : "",
8702 cur_field_name_2));
8703
8704 /*
8705 Compare the two columns and check for duplicate common fields.
8706 A common field is duplicate either if it was already found in
8707 table_ref_2 (then found == true), or if a field in table_ref_2
8708 was already matched by some previous field in table_ref_1
8709 (then cur_nj_col_2->is_common == true).
8710 Note that it is too early to check the columns outside of the
8711 USING list for ambiguity because they are not actually "referenced"
8712 here. These columns must be checked only on unqualified reference
8713 by name (e.g. in SELECT list).
8714 */
8715
3/4
✓ Branch 0 taken 5496887 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71842 times.
✓ Branch 3 taken 5425045 times.
5496887 if (!my_strcasecmp(system_charset_info, field_name_1, cur_field_name_2)) {
8716
3/8
✓ Branch 0 taken 71842 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 71842 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 71842 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
71842 DBUG_PRINT("info", ("match c1.is_common=%d", nj_col_1->is_common));
8717
4/4
✓ Branch 0 taken 71801 times.
✓ Branch 1 taken 41 times.
✓ Branch 2 taken 509 times.
✓ Branch 3 taken 71292 times.
71842 if (cur_nj_col_2->is_common ||
8718
4/4
✓ Branch 0 taken 505 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 500 times.
509 (found && (!using_fields || is_using_column_1))) {
8719
1/2
✓ Branch 0 taken 50 times.
✗ Branch 1 not taken.
50 my_error(ER_NON_UNIQ_ERROR, MYF(0), field_name_1, thd->where);
8720 50 return true;
8721 }
8722 71792 nj_col_2 = cur_nj_col_2;
8723 71792 found = true;
8724 }
8725 }
8726
4/4
✓ Branch 0 taken 20484 times.
✓ Branch 1 taken 281661 times.
✓ Branch 2 taken 12781 times.
✓ Branch 3 taken 7703 times.
302145 if (first_outer_loop && leaf_2) {
8727 /*
8728 Make sure that the next inner loop "knows" that all columns
8729 are materialized already.
8730 */
8731 12781 leaf_2->is_join_columns_complete = true;
8732 12781 first_outer_loop = false;
8733 }
8734
2/2
✓ Branch 0 taken 230862 times.
✓ Branch 1 taken 71283 times.
302145 if (!found) continue; // No matching field
8735
8736 /*
8737 field_1 and field_2 have the same names. Check if they are in the USING
8738 clause (if present), mark them as common fields, and add a new
8739 equi-join condition to the ON clause.
8740 */
8741
5/6
✓ Branch 0 taken 71283 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68561 times.
✓ Branch 3 taken 2722 times.
✓ Branch 4 taken 12177 times.
✓ Branch 5 taken 56384 times.
71283 if (nj_col_2 && (!using_fields || is_using_column_1)) {
8742
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 Item *item_1 = nj_col_1->create_item(thd);
8743
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14899 times.
14899 if (!item_1) return true;
8744
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 Item *item_2 = nj_col_2->create_item(thd);
8745
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14899 times.
14899 if (!item_2) return true;
8746
8747
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 Field *field_1 = nj_col_1->field();
8748
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 Field *field_2 = nj_col_2->field();
8749 Item_ident *item_ident_1, *item_ident_2;
8750 Item_func_eq *eq_cond;
8751
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 fields.push_back(field_1);
8752
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 fields.push_back(field_2);
8753
8754 /*
8755 The created items must be of sub-classes of Item_ident.
8756 */
8757
5/8
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 92 times.
✓ Branch 3 taken 14807 times.
✓ Branch 4 taken 92 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 92 times.
14899 assert(item_1->type() == Item::FIELD_ITEM ||
8758 item_1->type() == Item::REF_ITEM);
8759
5/8
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 745 times.
✓ Branch 3 taken 14154 times.
✓ Branch 4 taken 745 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 745 times.
14899 assert(item_2->type() == Item::FIELD_ITEM ||
8760 item_2->type() == Item::REF_ITEM);
8761
8762 /*
8763 We need to cast item_1,2 to Item_ident, because we need to hook name
8764 resolution contexts specific to each item.
8765 */
8766 14899 item_ident_1 = (Item_ident *)item_1;
8767 14899 item_ident_2 = (Item_ident *)item_2;
8768 /*
8769 Create and hook special name resolution contexts to each item in the
8770 new join condition . We need this to both speed-up subsequent name
8771 resolution of these items, and to enable proper name resolution of
8772 the items during the execute phase of PS.
8773 */
8774
3/6
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14899 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14899 times.
29798 if (set_new_item_local_context(thd, item_ident_1, nj_col_1->table_ref) ||
8775
2/4
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 14899 times.
14899 set_new_item_local_context(thd, item_ident_2, nj_col_2->table_ref))
8776 return true;
8777
8778
3/6
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14899 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14899 times.
14899 if (!(eq_cond = new Item_func_eq(item_ident_1, item_ident_2)))
8779 return true; // Out of memory.
8780
8781 /*
8782 Add the new equi-join condition to the ON clause. Notice that
8783 fix_fields() is applied to all ON conditions in setup_conds()
8784 so we don't do it here.
8785 */
8786
1/2
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
14899 add_join_on(table_ref_2, eq_cond);
8787
8788 14899 nj_col_1->is_common = nj_col_2->is_common = true;
8789
3/24
✓ Branch 0 taken 14899 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14899 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 14899 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
14899 DBUG_PRINT("info", ("%s.%s and %s.%s are common",
8790 nj_col_1->table_name() ? nj_col_1->table_name() : "",
8791 nj_col_1->name(),
8792 nj_col_2->table_name() ? nj_col_2->table_name() : "",
8793 nj_col_2->name()));
8794
8795 // Mark fields in the read set
8796
2/2
✓ Branch 0 taken 14807 times.
✓ Branch 1 taken 92 times.
14899 if (field_1) {
8797
1/2
✓ Branch 0 taken 14807 times.
✗ Branch 1 not taken.
14807 nj_col_1->table_ref->table->mark_column_used(field_1,
8798 MARK_COLUMNS_READ);
8799 } else {
8800 92 Mark_field mf(MARK_COLUMNS_READ);
8801
1/2
✓ Branch 0 taken 92 times.
✗ Branch 1 not taken.
92 item_1->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
8802 (uchar *)&mf);
8803 }
8804
8805
2/2
✓ Branch 0 taken 14154 times.
✓ Branch 1 taken 745 times.
14899 if (field_2) {
8806
1/2
✓ Branch 0 taken 14154 times.
✗ Branch 1 not taken.
14154 nj_col_2->table_ref->table->mark_column_used(field_2,
8807 MARK_COLUMNS_READ);
8808 } else {
8809 745 Mark_field mf(MARK_COLUMNS_READ);
8810
1/2
✓ Branch 0 taken 745 times.
✗ Branch 1 not taken.
745 item_2->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
8811 (uchar *)&mf);
8812 }
8813
8814
2/2
✓ Branch 0 taken 12177 times.
✓ Branch 1 taken 2722 times.
14899 if (using_fields != nullptr) ++(*found_using_fields);
8815 }
8816 }
8817
8818
2/2
✓ Branch 0 taken 13312 times.
✓ Branch 1 taken 137 times.
13449 if (leaf_1) leaf_1->is_join_columns_complete = true;
8819
8820 /*
8821 Everything is OK.
8822 Notice that at this point there may be some column names in the USING
8823 clause that are not among the common columns. This is an SQL error and
8824 we check for this error in store_natural_using_join_columns() when
8825 (found_using_fields < length(join_using_fields)).
8826 */
8827 13449 return false;
8828 13499 }
8829
8830 /*
8831 Materialize and store the row type of NATURAL/USING join.
8832
8833 SYNOPSIS
8834 store_natural_using_join_columns()
8835 thd current thread
8836 natural_using_join the table reference of the NATURAL/USING join
8837 table_ref_1 the first (left) operand (of a NATURAL/USING join).
8838 table_ref_2 the second (right) operand (of a NATURAL/USING join).
8839 using_fields if the join is JOIN...USING - the join columns,
8840 if NATURAL join, then NULL
8841 found_using_fields number of fields from the USING clause that were
8842 found among the common fields
8843
8844 DESCRIPTION
8845 Iterate over the columns of both join operands and sort and store
8846 all columns into the 'join_columns' list of natural_using_join
8847 where the list is formed by three parts:
8848 part1: The coalesced columns of table_ref_1 and table_ref_2,
8849 sorted according to the column order of the first table.
8850 part2: The other columns of the first table, in the order in
8851 which they were defined in CREATE TABLE.
8852 part3: The other columns of the second table, in the order in
8853 which they were defined in CREATE TABLE.
8854 Time complexity - O(N1+N2), where Ni = length(table_ref_i).
8855
8856 IMPLEMENTATION
8857 The procedure assumes that mark_common_columns() has been called
8858 for the join that is being processed.
8859
8860 RETURN
8861 true error: Some common column is ambiguous
8862 false OK
8863 */
8864
8865 13449 static bool store_natural_using_join_columns(THD *thd,
8866 TABLE_LIST *natural_using_join,
8867 TABLE_LIST *table_ref_1,
8868 TABLE_LIST *table_ref_2,
8869 List<String> *using_fields,
8870 uint found_using_fields) {
8871
2/4
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13449 times.
✗ Branch 3 not taken.
13449 Field_iterator_table_ref it_1, it_2;
8872 Natural_join_column *nj_col_1, *nj_col_2;
8873 List<Natural_join_column> *non_join_columns;
8874
1/2
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
13449 DBUG_TRACE;
8875
8876
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13449 times.
13449 assert(!natural_using_join->join_columns);
8877
8878
1/2
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
13449 Prepared_stmt_arena_holder ps_arena_holder(thd);
8879
8880
3/6
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13449 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 13449 times.
26898 if (!(non_join_columns = new (thd->mem_root) List<Natural_join_column>) ||
8881
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13449 times.
13449 !(natural_using_join->join_columns =
8882
1/2
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
13449 new (thd->mem_root) List<Natural_join_column>))
8883 return true;
8884
8885 /* Append the columns of the first join operand. */
8886
5/8
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 302090 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 315539 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 302090 times.
✓ Branch 7 taken 13449 times.
315539 for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next()) {
8887
1/2
✓ Branch 0 taken 302090 times.
✗ Branch 1 not taken.
302090 nj_col_1 = it_1.get_natural_column_ref();
8888
2/2
✓ Branch 0 taken 14850 times.
✓ Branch 1 taken 287240 times.
302090 if (nj_col_1->is_common) {
8889
1/2
✓ Branch 0 taken 14850 times.
✗ Branch 1 not taken.
14850 natural_using_join->join_columns->push_back(nj_col_1);
8890 /* Reset the common columns for the next call to mark_common_columns. */
8891 14850 nj_col_1->is_common = false;
8892 } else
8893
1/2
✓ Branch 0 taken 287240 times.
✗ Branch 1 not taken.
287240 non_join_columns->push_back(nj_col_1);
8894 }
8895
8896 /*
8897 Check that all columns in the USING clause are among the common
8898 columns. If this is not the case, report the first one that was
8899 not found in an error.
8900 */
8901
3/4
✓ Branch 0 taken 11145 times.
✓ Branch 1 taken 2304 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 11145 times.
13449 if (using_fields && found_using_fields < using_fields->elements) {
8902 String *using_field_name;
8903 List_iterator_fast<String> using_fields_it(*using_fields);
8904 while ((using_field_name = using_fields_it++)) {
8905 const char *using_field_name_ptr = using_field_name->c_ptr();
8906 List_iterator_fast<Natural_join_column> it(
8907 *(natural_using_join->join_columns));
8908 Natural_join_column *common_field;
8909
8910 for (;;) {
8911 /* If reached the end of fields, and none was found, report error. */
8912 if (!(common_field = it++)) {
8913 my_error(ER_BAD_FIELD_ERROR, MYF(0), using_field_name_ptr,
8914 thd->where);
8915 return true;
8916 }
8917 if (!my_strcasecmp(system_charset_info, common_field->name(),
8918 using_field_name_ptr))
8919 break; // Found match
8920 }
8921 }
8922 }
8923
8924 /* Append the non-equi-join columns of the second join operand. */
8925
5/8
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 153079 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 166528 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 153079 times.
✓ Branch 7 taken 13449 times.
166528 for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next()) {
8926
1/2
✓ Branch 0 taken 153079 times.
✗ Branch 1 not taken.
153079 nj_col_2 = it_2.get_natural_column_ref();
8927
2/2
✓ Branch 0 taken 138229 times.
✓ Branch 1 taken 14850 times.
153079 if (!nj_col_2->is_common)
8928
1/2
✓ Branch 0 taken 138229 times.
✗ Branch 1 not taken.
138229 non_join_columns->push_back(nj_col_2);
8929 else {
8930 /* Reset the common columns for the next call to mark_common_columns. */
8931 14850 nj_col_2->is_common = false;
8932 }
8933 }
8934
8935
2/2
✓ Branch 0 taken 10095 times.
✓ Branch 1 taken 3354 times.
13449 if (non_join_columns->elements > 0)
8936
1/2
✓ Branch 0 taken 10095 times.
✗ Branch 1 not taken.
10095 natural_using_join->join_columns->concat(non_join_columns);
8937 13449 natural_using_join->is_join_columns_complete = true;
8938
8939 13449 return false;
8940 13449 }
8941
8942 /*
8943 Precompute and store the row types of the top-most NATURAL/USING joins.
8944
8945 SYNOPSIS
8946 store_top_level_join_columns()
8947 thd current thread
8948 table_ref nested join or table in a FROM clause
8949 left_neighbor neighbor table reference to the left of table_ref at the
8950 same level in the join tree
8951 right_neighbor neighbor table reference to the right of table_ref at the
8952 same level in the join tree
8953
8954 DESCRIPTION
8955 The procedure performs a post-order traversal of a nested join tree
8956 and materializes the row types of NATURAL/USING joins in a
8957 bottom-up manner until it reaches the TABLE_LIST elements that
8958 represent the top-most NATURAL/USING joins. The procedure should be
8959 applied to each element of Query_block::top_join_list (i.e. to each
8960 top-level element of the FROM clause).
8961
8962 IMPLEMENTATION
8963 Notice that the table references in the list nested_join->join_list
8964 are in reverse order, thus when we iterate over it, we are moving
8965 from the right to the left in the FROM clause.
8966
8967 RETURN
8968 true Error
8969 false OK
8970 */
8971
8972 2229581 static bool store_top_level_join_columns(THD *thd, TABLE_LIST *table_ref,
8973 TABLE_LIST *left_neighbor,
8974 TABLE_LIST *right_neighbor) {
8975
1/2
✓ Branch 0 taken 2229581 times.
✗ Branch 1 not taken.
2229581 DBUG_TRACE;
8976
8977
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2229581 times.
2229581 assert(!table_ref->nested_join->natural_join_processed);
8978
8979
1/2
✓ Branch 0 taken 2229581 times.
✗ Branch 1 not taken.
2229581 Prepared_stmt_arena_holder ps_arena_holder(thd);
8980
8981 /* Call the procedure recursively for each nested table reference. */
8982
4/8
✓ Branch 0 taken 2229581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2229581 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2229581 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2229581 times.
✗ Branch 7 not taken.
2229581 if (table_ref->nested_join && !table_ref->nested_join->join_list.empty()) {
8983
1/2
✓ Branch 0 taken 2229581 times.
✗ Branch 1 not taken.
2229581 auto nested_it = table_ref->nested_join->join_list.begin();
8984
2/4
✓ Branch 0 taken 2229581 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2229580 times.
✗ Branch 3 not taken.
2229581 TABLE_LIST *same_level_left_neighbor = *nested_it++;
8985 2229580 TABLE_LIST *same_level_right_neighbor = nullptr;
8986 /* Left/right-most neighbors, possibly at higher levels in the join tree. */
8987 TABLE_LIST *real_left_neighbor, *real_right_neighbor;
8988
8989
2/2
✓ Branch 0 taken 4091489 times.
✓ Branch 1 taken 2229582 times.
6321071 while (same_level_left_neighbor) {
8990 4091489 TABLE_LIST *cur_table_ref = same_level_left_neighbor;
8991 4091491 same_level_left_neighbor =
8992
4/6
✓ Branch 0 taken 4091490 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4091490 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2229581 times.
✓ Branch 5 taken 1861909 times.
4091489 (nested_it == table_ref->nested_join->join_list.end()) ? nullptr
8993
2/4
✓ Branch 0 taken 1861910 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1861910 times.
✗ Branch 3 not taken.
1861909 : *nested_it++;
8994 /*
8995 Pick the parent's left and right neighbors if there are no immediate
8996 neighbors at the same level.
8997 */
8998 4091491 real_left_neighbor =
8999
2/2
✓ Branch 0 taken 1861910 times.
✓ Branch 1 taken 2229581 times.
4091491 (same_level_left_neighbor) ? same_level_left_neighbor : left_neighbor;
9000 4091491 real_right_neighbor = (same_level_right_neighbor)
9001
2/2
✓ Branch 0 taken 1861910 times.
✓ Branch 1 taken 2229581 times.
4091491 ? same_level_right_neighbor
9002 : right_neighbor;
9003
9004 9987322 if (cur_table_ref->nested_join &&
9005
5/6
✓ Branch 0 taken 1804340 times.
✓ Branch 1 taken 2287151 times.
✓ Branch 2 taken 1439399 times.
✓ Branch 3 taken 364941 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 4091491 times.
5530890 !cur_table_ref->nested_join->natural_join_processed &&
9006
2/4
✓ Branch 0 taken 1439399 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1439399 times.
1439399 store_top_level_join_columns(thd, cur_table_ref, real_left_neighbor,
9007 real_right_neighbor))
9008 return true;
9009 4091491 same_level_right_neighbor = cur_table_ref;
9010 }
9011 }
9012
9013 /*
9014 If this is a NATURAL/USING join, materialize its result columns and
9015 convert to a JOIN ... ON.
9016 */
9017
2/2
✓ Branch 0 taken 13499 times.
✓ Branch 1 taken 2216083 times.
2229582 if (table_ref->is_natural_join) {
9018
2/4
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13499 times.
✗ Branch 3 not taken.
13499 assert(table_ref->nested_join &&
9019 table_ref->nested_join->join_list.size() == 2);
9020
1/2
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
13499 auto operand_it = table_ref->nested_join->join_list.begin();
9021 /*
9022 Notice that the order of join operands depends on whether table_ref
9023 represents a LEFT or a RIGHT join. In a RIGHT join, the operands are
9024 in inverted order.
9025 */
9026
2/4
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13499 times.
✗ Branch 3 not taken.
13499 TABLE_LIST *table_ref_2 = *operand_it++; /* Second NATURAL join operand.*/
9027
2/4
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 13499 times.
✗ Branch 3 not taken.
13499 TABLE_LIST *table_ref_1 = *operand_it++; /* First NATURAL join operand. */
9028 13499 List<String> *using_fields = table_ref->join_using_fields;
9029 uint found_using_fields;
9030
9031
3/4
✓ Branch 0 taken 13499 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 13449 times.
13499 if (mark_common_columns(thd, table_ref_1, table_ref_2, using_fields,
9032 &found_using_fields))
9033 50 return true;
9034
9035
2/4
✓ Branch 0 taken 13449 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13449 times.
13449 if (store_natural_using_join_columns(thd, table_ref, table_ref_1,
9036 table_ref_2, using_fields,
9037 found_using_fields))
9038 return true;
9039
9040 /*
9041 Change NATURAL JOIN to JOIN ... ON. We do this for both operands
9042 because either one of them or the other is the one with the
9043 natural join flag because RIGHT joins are transformed into LEFT,
9044 and the two tables may be reordered.
9045 */
9046 13449 table_ref_1->natural_join = table_ref_2->natural_join = nullptr;
9047
9048 /* Add a true condition to outer joins that have no common columns. */
9049
6/6
✓ Branch 0 taken 8218 times.
✓ Branch 1 taken 5231 times.
✓ Branch 2 taken 48 times.
✓ Branch 3 taken 8170 times.
✓ Branch 4 taken 48 times.
✓ Branch 5 taken 13401 times.
13449 if (table_ref_2->outer_join && !table_ref_2->join_cond())
9050
1/2
✓ Branch 0 taken 48 times.
✗ Branch 1 not taken.
96 table_ref_2->set_join_cond(new Item_func_true());
9051
9052 /* Change this table reference to become a leaf for name resolution. */
9053
2/2
✓ Branch 0 taken 673 times.
✓ Branch 1 taken 12776 times.
13449 if (left_neighbor) {
9054 TABLE_LIST *last_leaf_on_the_left;
9055
1/2
✓ Branch 0 taken 673 times.
✗ Branch 1 not taken.
673 last_leaf_on_the_left = left_neighbor->last_leaf_for_name_resolution();
9056 673 last_leaf_on_the_left->next_name_resolution_table = table_ref;
9057 }
9058
2/2
✓ Branch 0 taken 4880 times.
✓ Branch 1 taken 8569 times.
13449 if (right_neighbor) {
9059 TABLE_LIST *first_leaf_on_the_right;
9060 first_leaf_on_the_right =
9061
1/2
✓ Branch 0 taken 4880 times.
✗ Branch 1 not taken.
4880 right_neighbor->first_leaf_for_name_resolution();
9062 4880 table_ref->next_name_resolution_table = first_leaf_on_the_right;
9063 } else
9064 8569 table_ref->next_name_resolution_table = nullptr;
9065 }
9066
9067 2229532 table_ref->nested_join->natural_join_processed = true;
9068
9069 2229532 return false;
9070 2229582 }
9071
9072 /*
9073 Compute and store the row types of the top-most NATURAL/USING joins
9074 in a FROM clause.
9075
9076 SYNOPSIS
9077 setup_natural_join_row_types()
9078 thd current thread
9079 from_clause list of top-level table references in a FROM clause
9080
9081 DESCRIPTION
9082 Apply the procedure 'store_top_level_join_columns' to each of the
9083 top-level table references of the FROM clause. Adjust the list of tables
9084 for name resolution - context->first_name_resolution_table to the
9085 top-most, lef-most NATURAL/USING join.
9086
9087 IMPLEMENTATION
9088 Notice that the table references in 'from_clause' are in reverse
9089 order, thus when we iterate over it, we are moving from the right
9090 to the left in the FROM clause.
9091
9092 RETURN
9093 true Error
9094 false OK
9095 */
9096 854095 bool setup_natural_join_row_types(THD *thd,
9097 mem_root_deque<TABLE_LIST *> *from_clause,
9098 Name_resolution_context *context) {
9099
1/2
✓ Branch 0 taken 854095 times.
✗ Branch 1 not taken.
854095 DBUG_TRACE;
9100 854095 thd->where = "from clause";
9101
2/4
✓ Branch 0 taken 854095 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 854095 times.
854095 if (from_clause->empty())
9102 return false; /* We come here in the case of UNIONs. */
9103
9104
1/2
✓ Branch 0 taken 854095 times.
✗ Branch 1 not taken.
854095 auto table_ref_it = from_clause->begin();
9105 /* Table reference to the left of the current. */
9106
2/4
✓ Branch 0 taken 854095 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 854095 times.
✗ Branch 3 not taken.
854095 TABLE_LIST *left_neighbor = *table_ref_it++;
9107 /* Table reference to the right of the current. */
9108 854095 TABLE_LIST *right_neighbor = nullptr;
9109
9110 /* Note that tables in the list are in reversed order */
9111
2/2
✓ Branch 0 taken 934405 times.
✓ Branch 1 taken 854045 times.
1788450 while (left_neighbor) {
9112 /* Current table reference. */
9113 934405 TABLE_LIST *table_ref = left_neighbor;
9114 934405 left_neighbor =
9115
6/10
✓ Branch 0 taken 934405 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 934405 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 854095 times.
✓ Branch 5 taken 80310 times.
✓ Branch 6 taken 80310 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 80310 times.
✗ Branch 9 not taken.
934405 (table_ref_it == from_clause->end()) ? nullptr : *table_ref_it++;
9116
9117 /*
9118 Do not redo work if already done:
9119 - for prepared statements and stored procedures,
9120 - if already processed inside a derived table/view.
9121 */
9122
2/2
✓ Branch 0 taken 790232 times.
✓ Branch 1 taken 144173 times.
934405 if (table_ref->nested_join &&
9123
2/2
✓ Branch 0 taken 790182 times.
✓ Branch 1 taken 50 times.
790232 !table_ref->nested_join->natural_join_processed) {
9124
3/4
✓ Branch 0 taken 790182 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 50 times.
✓ Branch 3 taken 790132 times.
790182 if (store_top_level_join_columns(thd, table_ref, left_neighbor,
9125 right_neighbor))
9126 50 return true;
9127 }
9128
3/4
✓ Branch 0 taken 80310 times.
✓ Branch 1 taken 854045 times.
✓ Branch 2 taken 80310 times.
✗ Branch 3 not taken.
934355 if (left_neighbor && context->query_block->first_execution) {
9129 80310 left_neighbor->next_name_resolution_table =
9130
1/2
✓ Branch 0 taken 80310 times.
✗ Branch 1 not taken.
80310 table_ref->first_leaf_for_name_resolution();
9131 }
9132 934355 right_neighbor = table_ref;
9133 }
9134
9135 /*
9136 Store the top-most, left-most NATURAL/USING join, so that we start
9137 the search from that one instead of context->table_list. At this point
9138 right_neighbor points to the left-most top-level table reference in the
9139 FROM clause.
9140 */
9141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 854045 times.
854045 assert(right_neighbor);
9142 854044 context->first_name_resolution_table =
9143
1/2
✓ Branch 0 taken 854044 times.
✗ Branch 1 not taken.
854045 right_neighbor->first_leaf_for_name_resolution();
9144
9145 854044 return false;
9146 854094 }
9147
9148 /**
9149 Resolve variable assignments from LEX object
9150
9151 @param thd Thread handler
9152 @param lex Lex object containing variable assignments
9153
9154 @returns false if success, true if error
9155
9156 @note
9157 set_entry() must be called before fix_fields() of the whole list of
9158 field items because:
9159
9160 1) the list of field items has same order as in the query, and the
9161 Item_func_get_user_var item may go before the Item_func_set_user_var:
9162
9163 @verbatim
9164 SELECT @a, @a := 10 FROM t;
9165 @endverbatim
9166
9167 2) The entry->update_query_id value controls constantness of
9168 Item_func_get_user_var items, so in presence of Item_func_set_user_var
9169 items we have to refresh their entries before fixing of
9170 Item_func_get_user_var items.
9171 */
9172
9173 4420 bool resolve_var_assignments(THD *thd, LEX *lex) {
9174
1/2
✓ Branch 0 taken 4420 times.
✗ Branch 1 not taken.
4420 List_iterator<Item_func_set_user_var> li(lex->set_var_list);
9175 Item_func_set_user_var *var;
9176
3/4
✓ Branch 0 taken 5436 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5436 times.
✓ Branch 3 taken 4420 times.
9856 while ((var = li++)) var->set_entry(thd, false);
9177
9178 4420 return false;
9179 }
9180
9181 /****************************************************************************
9182 ** Check that all given fields exists and fill struct with current data
9183 ****************************************************************************/
9184
9185 /**
9186 Resolve a list of expressions and setup appropriate data
9187
9188 @param thd thread handler
9189 @param want_privilege privilege representing desired operation.
9190 whether the expressions are selected, inserted
9191 or updated, or no operation is done.
9192 will also decide inclusion in read/write maps.
9193 @param allow_sum_func true if set operations are allowed in context.
9194 @param column_update if true, reject expressions that do not resolve
9195 to a base table column
9196 @param split_sum_funcs If true, Item::split_sum_func will add hidden
9197 items to "fields". See also description in its
9198 helper method Item::split_sum_func2.
9199 @param typed_items List of reference items for type derivation
9200 May be nullptr.
9201 @param[in,out] fields list of expressions, populated with resolved
9202 data about expressions.
9203 @param[out] ref_item_array filled in with references to items.
9204
9205 @retval false if success
9206 @retval true if error
9207
9208 @note The function checks updatability/insertability for the table before
9209 checking column privileges, for consistent error reporting.
9210 This has consequences for columns that are specified to be updated:
9211 The column is first resolved without privilege check.
9212 This check is followed by an updatablity/insertability check.
9213 Finally, a column privilege check is run, and the column is marked
9214 for update.
9215 */
9216
9217 18988654 bool setup_fields(THD *thd, ulong want_privilege, bool allow_sum_func,
9218 bool split_sum_funcs, bool column_update,
9219 const mem_root_deque<Item *> *typed_items,
9220 mem_root_deque<Item *> *fields,
9221 Ref_item_array ref_item_array) {
9222
1/2
✓ Branch 0 taken 18989114 times.
✗ Branch 1 not taken.
18988654 DBUG_TRACE;
9223
9224 18989114 Query_block *const select = thd->lex->current_query_block();
9225 18989079 const enum_mark_columns save_mark_used_columns = thd->mark_used_columns;
9226 18989079 nesting_map save_allow_sum_func = thd->lex->allow_sum_func;
9227 Column_privilege_tracker column_privilege(thd,
9228
2/2
✓ Branch 0 taken 3922467 times.
✓ Branch 1 taken 15066612 times.
18989079 column_update ? 0 : want_privilege);
9229
9230 // Function can only be used to set up one specific operation:
9231
7/8
✓ Branch 0 taken 18303885 times.
✓ Branch 1 taken 685019 times.
✓ Branch 2 taken 3935333 times.
✓ Branch 3 taken 14368552 times.
✓ Branch 4 taken 137414 times.
✓ Branch 5 taken 3797919 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 137414 times.
18988904 assert(want_privilege == 0 || want_privilege == SELECT_ACL ||
9232 want_privilege == INSERT_ACL || want_privilege == UPDATE_ACL);
9233
3/4
✓ Branch 0 taken 3922452 times.
✓ Branch 1 taken 15066452 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 3922452 times.
18988904 assert(!(column_update && (want_privilege & SELECT_ACL)));
9234
2/2
✓ Branch 0 taken 14368542 times.
✓ Branch 1 taken 4620362 times.
18988904 if (want_privilege & SELECT_ACL)
9235 14368542 thd->mark_used_columns = MARK_COLUMNS_READ;
9236
4/4
✓ Branch 0 taken 3935334 times.
✓ Branch 1 taken 685028 times.
✓ Branch 2 taken 12876 times.
✓ Branch 3 taken 3922458 times.
4620362 else if (want_privilege & (INSERT_ACL | UPDATE_ACL) && !column_update)
9237 12876 thd->mark_used_columns = MARK_COLUMNS_WRITE;
9238 else
9239 4607486 thd->mark_used_columns = MARK_COLUMNS_NONE;
9240
9241
5/8
✓ Branch 0 taken 18988932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18988989 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 113 times.
✓ Branch 5 taken 18988876 times.
✓ Branch 6 taken 113 times.
✗ Branch 7 not taken.
18988904 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
9242
2/2
✓ Branch 0 taken 9518867 times.
✓ Branch 1 taken 9470122 times.
18988989 if (allow_sum_func)
9243 9518867 thd->lex->allow_sum_func |= (nesting_map)1 << select->nest_level;
9244 18988989 thd->where = THD::DEFAULT_WHERE;
9245 18988989 bool save_is_item_list_lookup = select->is_item_list_lookup;
9246 18988989 select->is_item_list_lookup = false;
9247
9248 /*
9249 To prevent fail on forward lookup we fill it with zerows,
9250 then if we got pointer on zero after find_item_in_list we will know
9251 that it is forward lookup.
9252
9253 There is other way to solve problem: fill array with pointers to list,
9254 but it will be slower.
9255 */
9256
2/2
✓ Branch 0 taken 9518867 times.
✓ Branch 1 taken 9469884 times.
18988989 if (!ref_item_array.is_null()) {
9257
1/2
✓ Branch 0 taken 9518867 times.
✗ Branch 1 not taken.
9518867 size_t num_visible_fields = CountVisibleFields(*fields);
9258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9518861 times.
9518867 assert(ref_item_array.size() >= num_visible_fields);
9259 9518861 memset(ref_item_array.array(), 0, sizeof(Item *) * num_visible_fields);
9260 }
9261
9262 18988747 Ref_item_array ref = ref_item_array;
9263
9264 18988747 mem_root_deque<Item *>::const_iterator typed_it;
9265
2/2
✓ Branch 0 taken 5534772 times.
✓ Branch 1 taken 13453975 times.
18988747 if (typed_items != nullptr) {
9266
1/2
✓ Branch 0 taken 5534806 times.
✗ Branch 1 not taken.
5534772 typed_it = typed_items->begin();
9267 }
9268
6/10
✓ Branch 0 taken 18988866 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 68267151 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 87255877 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 87256256 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 68270476 times.
✓ Branch 9 taken 18985780 times.
87255791 for (auto it = fields->begin(); it != fields->end(); ++it) {
9269 68270476 const size_t old_size = fields->size();
9270
1/2
✓ Branch 0 taken 68270529 times.
✗ Branch 1 not taken.
68270493 Item *item = *it;
9271
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 68270529 times.
68270529 assert(!item->hidden);
9272
1/2
✓ Branch 0 taken 68270554 times.
✗ Branch 1 not taken.
68270529 Item **item_pos = &*it;
9273
7/8
✓ Branch 0 taken 38276866 times.
✓ Branch 1 taken 29993688 times.
✓ Branch 2 taken 38276865 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 38273834 times.
✓ Branch 5 taken 3031 times.
✓ Branch 6 taken 3047 times.
✓ Branch 7 taken 68267149 times.
136537719 if ((!item->fixed && item->fix_fields(thd, item_pos)) ||
9274
3/4
✓ Branch 0 taken 68267165 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✓ Branch 3 taken 68267149 times.
68267522 (item = *item_pos)->check_cols(1)) {
9275
5/8
✓ Branch 0 taken 3047 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3047 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3046 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
3047 DBUG_PRINT("info",
9276 ("thd->mark_used_columns: %d", thd->mark_used_columns));
9277 3190 return true; /* purecov: inspected */
9278 }
9279
9280 // Check that we don't have a field that is hidden system field. This should
9281 // be caught in Item_field::fix_fields.
9282
5/8
✓ Branch 0 taken 68267066 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 26847002 times.
✓ Branch 3 taken 41420064 times.
✓ Branch 4 taken 26847018 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 26847018 times.
68267149 assert(
9283 item->type() != Item::FIELD_ITEM ||
9284 !static_cast<const Item_field *>(item)->field->is_hidden_by_system());
9285
9286
2/2
✓ Branch 0 taken 24609481 times.
✓ Branch 1 taken 43657972 times.
68267082 if (!ref.is_null()) {
9287 24609481 ref[0] = item;
9288 24609482 ref.pop_front();
9289 }
9290 68267435 Item *typed_item = nullptr;
9291
8/10
✓ Branch 0 taken 25263083 times.
✓ Branch 1 taken 43004352 times.
✓ Branch 2 taken 25263175 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25263186 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 25263179 times.
✓ Branch 7 taken 7 times.
✓ Branch 8 taken 25263218 times.
✓ Branch 9 taken 43004320 times.
68267435 if (typed_items != nullptr && typed_it != typed_items->end()) {
9292
2/4
✓ Branch 0 taken 25262818 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 25263078 times.
✗ Branch 3 not taken.
25263218 typed_item = *typed_it++;
9293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25263078 times.
25263078 assert(!typed_item->hidden);
9294 }
9295
9296
2/2
✓ Branch 0 taken 18543133 times.
✓ Branch 1 taken 49724265 times.
68267398 if (column_update) {
9297
1/2
✓ Branch 0 taken 18543122 times.
✗ Branch 1 not taken.
18543133 Item_field *const field = item->field_for_view_update();
9298
2/2
✓ Branch 0 taken 23 times.
✓ Branch 1 taken 18543099 times.
18543122 if (field == nullptr) {
9299
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->item_name.ptr());
9300 143 return true;
9301 }
9302
2/4
✓ Branch 0 taken 18543115 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18543115 times.
18543099 if (item->type() == Item::TRIGGER_FIELD_ITEM) {
9303 char buff[NAME_LEN * 2];
9304 String str(buff, sizeof(buff), &my_charset_bin);
9305 str.length(0);
9306 item->print(thd, &str, QT_ORDINARY);
9307 my_error(ER_INVALID_ASSIGNMENT_TARGET, MYF(0), str.c_ptr());
9308 return true;
9309 }
9310 18543115 TABLE_LIST *tr = field->table_ref;
9311
6/6
✓ Branch 0 taken 183090 times.
✓ Branch 1 taken 18360025 times.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 183061 times.
✓ Branch 4 taken 31 times.
✓ Branch 5 taken 18543086 times.
18543115 if ((want_privilege & UPDATE_ACL) && !tr->is_updatable()) {
9312 /*
9313 The base table of the column may have beeen referenced through a view
9314 or derived table. If so, print the name of the upper-most view
9315 referring to this table in order to print the error message with the
9316 alias of the view as written in the original query instead of the
9317 alias of the base table.
9318 */
9319
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 my_error(ER_NON_UPDATABLE_TABLE, MYF(0), tr->top_table()->alias,
9320 "UPDATE");
9321 31 return true;
9322 }
9323
4/6
✓ Branch 0 taken 18360012 times.
✓ Branch 1 taken 183074 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 18360022 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 18543096 times.
18543086 if ((want_privilege & INSERT_ACL) && !tr->is_insertable()) {
9324 /* purecov: begin inspected */
9325 /*
9326 Generally unused as long as INSERT only can be applied against
9327 one base table, for which the INSERT privileges are checked in
9328 Sql_cmd_insert_base::prepare_inner()
9329 */
9330 my_error(ER_NON_INSERTABLE_TABLE, MYF(0), tr->top_table()->alias,
9331 "INSERT");
9332 return true;
9333 /* purecov: end */
9334 }
9335
2/2
✓ Branch 0 taken 18543078 times.
✓ Branch 1 taken 18 times.
18543096 if (want_privilege & (INSERT_ACL | UPDATE_ACL)) {
9336 18543078 Column_privilege_tracker column_privilege_tr(thd, want_privilege);
9337
3/4
✓ Branch 0 taken 18543122 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 90 times.
✓ Branch 3 taken 18543032 times.
18543083 if (item->walk(&Item::check_column_privileges, enum_walk::PREFIX,
9338 pointer_cast<uchar *>(thd)))
9339 90 return true;
9340
2/2
✓ Branch 0 taken 18543033 times.
✓ Branch 1 taken 89 times.
18543122 }
9341 18543051 Mark_field mf(MARK_COLUMNS_WRITE);
9342
1/2
✓ Branch 0 taken 18543036 times.
✗ Branch 1 not taken.
18543007 item->walk(&Item::mark_field_in_map, enum_walk::POSTFIX,
9343 pointer_cast<uchar *>(&mf));
9344
2/2
✓ Branch 0 taken 140882 times.
✓ Branch 1 taken 49583082 times.
49724265 } else if (item->data_type() == MYSQL_TYPE_INVALID) {
9345
2/2
✓ Branch 0 taken 140146 times.
✓ Branch 1 taken 736 times.
140882 if (typed_item != nullptr) {
9346
3/6
✓ Branch 0 taken 140146 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 140146 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 140146 times.
140146 if (item->propagate_type(thd, Type_properties(*typed_item)))
9347 return true;
9348 } else {
9349
3/6
✓ Branch 0 taken 736 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 736 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 736 times.
736 if (item->propagate_type(thd, item->default_data_type())) return true;
9350 }
9351 }
9352
9353
2/2
✓ Branch 0 taken 24609475 times.
✓ Branch 1 taken 43657525 times.
68267000 if (split_sum_funcs) {
9354 /*
9355 (1) Contains a grouped aggregate but is not one. If it is one, we do
9356 not split, but in create_tmp_table() we look at its arguments and add
9357 them to the tmp table, which achieves the same result as for window
9358 functions in (2) but differently.
9359 @todo: unify this (do like (2), probably).
9360 (2) Contains a window function. Even if it is a window function, we
9361 have to collect its arguments and add them to the hidden list of
9362 items, as those arguments have to be stored in the first tmp tables,
9363 and carried forward up to the tmp table where the WF can be
9364 evaluated.
9365 */
9366
3/4
✓ Branch 0 taken 857018 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 587504 times.
✓ Branch 3 taken 269514 times.
25466493 if ((item->has_aggregation() && !(item->type() == Item::SUM_FUNC_ITEM &&
9367
8/8
✓ Branch 0 taken 857018 times.
✓ Branch 1 taken 23752456 times.
✓ Branch 2 taken 587428 times.
✓ Branch 3 taken 76 times.
✓ Branch 4 taken 4283 times.
✓ Branch 5 taken 24335604 times.
✓ Branch 6 taken 273873 times.
✓ Branch 7 taken 24335604 times.
49806379 !item->m_is_window_function)) || //(1)
9368 24339884 item->has_wf()) // (2)
9369
1/2
✓ Branch 0 taken 273873 times.
✗ Branch 1 not taken.
273873 item->split_sum_func(thd, ref_item_array, fields);
9370 }
9371
9372
1/2
✓ Branch 0 taken 68266774 times.
✗ Branch 1 not taken.
68267002 select->select_list_tables |= item->used_tables();
9373
9374
2/2
✓ Branch 0 taken 272396 times.
✓ Branch 1 taken 67994614 times.
68266774 if (old_size != fields->size()) {
9375 // Items have been added (either by fix_fields or by split_sum_func), so
9376 // our iterator is invalidated. Reconstruct it.
9377
3/6
✓ Branch 0 taken 272396 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 272396 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 272396 times.
✗ Branch 5 not taken.
272396 it = std::find(fields->begin(), fields->end(), item);
9378 }
9379 }
9380 18985780 select->is_item_list_lookup = save_is_item_list_lookup;
9381 18985780 thd->lex->allow_sum_func = save_allow_sum_func;
9382 18985780 thd->mark_used_columns = save_mark_used_columns;
9383
5/8
✓ Branch 0 taken 18985517 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 18985517 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 112 times.
✓ Branch 5 taken 18985405 times.
✓ Branch 6 taken 112 times.
✗ Branch 7 not taken.
18985780 DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns));
9384
9385
2/4
✓ Branch 0 taken 18985564 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 18985564 times.
18985517 assert(!thd->is_error());
9386 18985564 return false;
9387 18988754 }
9388
9389 /**
9390 This is an iterator which emits leaf TABLE_LIST nodes in an order suitable
9391 for expansion of 'table_name.*' (qualified asterisk) or '*' (unqualified),
9392 fur use by insert_fields().
9393
9394 First here is some background.
9395
9396 1.
9397 SELECT T1.*, T2.* FROM T1 NATURAL JOIN T2;
9398 has to return all columns of T1 and then all of T2's;
9399 whereas
9400 SELECT * FROM T1 NATURAL JOIN T2;
9401 has to return all columns of T1 and then only those of T2's which are not
9402 common with T1.
9403 Thus, in the first case a NATURAL JOIN isn't considered a leaf (we have to
9404 see through it to find T1.* and T2.*), in the second case it is (we have
9405 to ask it for its column set).
9406 In the first case, the place to search for tables is thus the
9407 TABLE_LIST::next_local list; in the second case it is
9408 TABLE_LIST::next_name_resolution_table.
9409
9410 2.
9411 SELECT * FROM T1 RIGHT JOIN T2 ON < cond >;
9412 is converted, during contextualization, to:
9413 SELECT * FROM T2 LEFT JOIN T1 ON < cond >;
9414 however the former has to return columns of T1 then of T2,
9415 while the latter has to return T2's then T1's.
9416 The conversion has been complete: the lists 'next_local',
9417 'next_name_resolution_table' and Query_block::join_list are as if the user
9418 had typed the second query.
9419
9420 Now to the behaviour of this iterator.
9421
9422 A. If qualified asterisk, the emission order is irrelevant as the caller
9423 tests the table's name; and a NATURAL JOIN isn't a leaf. So, we just follow
9424 the TABLE_LIST::next_local pointers.
9425
9426 B. If non-qualified asterisk, the order must be the left-to-right order
9427 as it was in the query entered by the user. And a NATURAL JOIN is a leaf. So:
9428
9429 B.i. if there was no RIGHT JOIN, then the user-input order is just that of
9430 the 'next_name_resolution' pointers.
9431
9432 B.ii. otherwise, then the order has to be found by a more complex procedure
9433 (function build_vec()):
9434 - first we traverse the join operators, taking into account operators
9435 which had a conversion from RIGHT to LEFT JOIN, we recreate the user-input
9436 order and store leaf TABLE_LISTs in that order in a vector.
9437 - then, in the emission phase, we just emit tables from the vector.
9438
9439 Sequence of calls: constructor, init(), [get_next() N times], destructor.
9440 */
9441 class Tables_in_user_order_iterator {
9442 public:
9443 681922 void init(Query_block *query_block, bool qualified) {
9444
2/4
✓ Branch 0 taken 681922 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 681922 times.
✗ Branch 3 not taken.
681922 assert(query_block && !m_query_block);
9445 681922 m_query_block = query_block;
9446 681922 m_qualified = qualified;
9447 // Vector is needed only if '*' is not qualified and there were RIGHT JOINs
9448
2/2
✓ Branch 0 taken 4443 times.
✓ Branch 1 taken 677479 times.
681922 if (m_qualified) {
9449 4443 m_next = m_query_block->context.table_list;
9450 4443 return;
9451 }
9452
2/2
✓ Branch 0 taken 677183 times.
✓ Branch 1 taken 296 times.
677479 if (!m_query_block->right_joins()) {
9453 677183 m_next = m_query_block->context.first_name_resolution_table;
9454 677183 return;
9455 }
9456 296 m_next = nullptr;
9457 296 m_vec = new std::vector<TABLE_LIST *>;
9458 296 fill_vec(*m_query_block->join_list);
9459 }
9460 681922 ~Tables_in_user_order_iterator() {
9461
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 681626 times.
681922 delete m_vec;
9462 681922 m_vec = nullptr;
9463 681922 }
9464 1374214 TABLE_LIST *get_next() {
9465
2/2
✓ Branch 0 taken 1373342 times.
✓ Branch 1 taken 872 times.
1374214 if (m_vec == nullptr) {
9466 1373342 auto cur = m_next;
9467
2/2
✓ Branch 0 taken 691754 times.
✓ Branch 1 taken 681588 times.
1373342 if (cur)
9468 691754 m_next =
9469
2/2
✓ Branch 0 taken 5927 times.
✓ Branch 1 taken 685827 times.
691754 m_qualified ? cur->next_local : cur->next_name_resolution_table;
9470 1373342 return cur;
9471 }
9472
2/2
✓ Branch 0 taken 296 times.
✓ Branch 1 taken 576 times.
872 if (m_next_vec_pos == m_vec->size()) return nullptr;
9473 576 return (*m_vec)[m_next_vec_pos++];
9474 }
9475
9476 private:
9477 /// Fills the vector
9478 /// @param tables list of tables and join operators
9479 574 void fill_vec(const mem_root_deque<TABLE_LIST *> &tables) {
9480
5/6
✓ Branch 0 taken 574 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 154 times.
✓ Branch 3 taken 420 times.
✓ Branch 4 taken 154 times.
✓ Branch 5 taken 420 times.
574 if (tables.size() != 0 && tables.front()->join_order_swapped) {
9481
2/4
✓ Branch 0 taken 154 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 154 times.
✗ Branch 3 not taken.
154 assert(tables.size() == 2 && !tables.back()->join_order_swapped);
9482 154 add_table(tables.front());
9483 154 add_table(tables.back());
9484 154 return;
9485 }
9486 // Walk from end to beginning, as join_list is always "reversed"
9487 // (e.g. T1 INNER JOIN T2 leads to join_list = (T2,T1)):
9488
8/14
✓ Branch 0 taken 420 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 546 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 546 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 546 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 966 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 966 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 546 times.
✓ Branch 13 taken 420 times.
966 for (auto it = tables.rbegin(); it != tables.rend(); ++it) add_table(*it);
9489 }
9490 854 void add_table(TABLE_LIST *tr) {
9491
2/2
✓ Branch 0 taken 576 times.
✓ Branch 1 taken 278 times.
854 if (tr->is_leaf_for_name_resolution()) // stop diving here
9492 576 return m_vec->push_back(tr);
9493
1/2
✓ Branch 0 taken 278 times.
✗ Branch 1 not taken.
278 if (tr->nested_join != nullptr) // do dive
9494 278 fill_vec(tr->nested_join->join_list);
9495 }
9496 // Query block which owns the FROM clause to search in
9497 Query_block *m_query_block{nullptr};
9498 /// True/false if we want to expand 'table_name.*' / '*'.
9499 bool m_qualified;
9500 /// If not using the vector: next table to emit
9501 TABLE_LIST *m_next;
9502 /// Vector for the complex case. As the complex case is expected to be rare,
9503 /// we allocate the vector only if needed. nullptr otherwise.
9504 std::vector<TABLE_LIST *> *m_vec{nullptr};
9505 /// If using the vector: position in vector, of next table to emit
9506 uint m_next_vec_pos{0};
9507 };
9508
9509 /*
9510 Drops in all fields instead of current '*' field
9511
9512 SYNOPSIS
9513 insert_fields()
9514 thd Thread handler
9515 query_block Query block
9516 db_name Database name in case of 'database_name.table_name.*'
9517 table_name Table name in case of 'table_name.*'
9518 it Pointer to '*'
9519 any_privileges 0 If we should ensure that we have SELECT privileges
9520 for all columns
9521 1 If any privilege is ok
9522 RETURN
9523 0 ok 'it' is updated to point at last inserted
9524 1 error. Error message is generated but not sent to client
9525 */
9526
9527 681922 bool insert_fields(THD *thd, Query_block *query_block, const char *db_name,
9528 const char *table_name, mem_root_deque<Item *> *fields,
9529 mem_root_deque<Item *>::iterator *it, bool any_privileges) {
9530 char name_buff[NAME_LEN + 1];
9531
1/2
✓ Branch 0 taken 681922 times.
✗ Branch 1 not taken.
681922 DBUG_TRACE;
9532
5/8
✓ Branch 0 taken 681922 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 681922 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
✓ Branch 5 taken 681912 times.
✓ Branch 6 taken 10 times.
✗ Branch 7 not taken.
681922 DBUG_PRINT("arena", ("stmt arena: %p", thd->stmt_arena));
9533
9534 // No need to expand '*' multiple times:
9535
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 681922 times.
681922 assert(query_block->first_execution);
9536
4/4
✓ Branch 0 taken 500 times.
✓ Branch 1 taken 681422 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 681913 times.
682422 if (db_name &&
9537
5/6
✓ Branch 0 taken 495 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 495 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4 times.
✓ Branch 5 taken 491 times.
500 (lower_case_table_names || is_infoschema_db(db_name, strlen(db_name)))) {
9538 /*
9539 convert database to lower case for comparison
9540 We can't do this in Item_field as this would change the
9541 'name' of the item which may be used in the select list
9542
9543 We lowercase the 'information_schema' name below to treat it as
9544 case-insensitive even in lower_case_table_names=0.
9545 */
9546
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 strmake(name_buff, db_name, sizeof(name_buff) - 1);
9547
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 my_casedn_str(files_charset_info, name_buff);
9548 9 db_name = name_buff;
9549 }
9550
9551 681922 bool found = false;
9552
9553 TABLE_LIST *tables;
9554
9555 681922 Tables_in_user_order_iterator user_it;
9556
1/2
✓ Branch 0 taken 681922 times.
✗ Branch 1 not taken.
681922 user_it.init(query_block, table_name != nullptr);
9557
9558 while (true) {
9559 1374214 tables = user_it.get_next();
9560
2/2
✓ Branch 0 taken 681884 times.
✓ Branch 1 taken 692330 times.
1374214 if (tables == nullptr) break;
9561
9562
1/2
✓ Branch 0 taken 692330 times.
✗ Branch 1 not taken.
692330 Field_iterator_table_ref field_iterator;
9563 692330 TABLE *const table = tables->table;
9564
9565
2/4
✓ Branch 0 taken 692330 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 692330 times.
692330 assert(tables->is_leaf_for_name_resolution());
9566
9567 699743 if ((table_name &&
9568
9/10
✓ Branch 0 taken 5927 times.
✓ Branch 1 taken 686403 times.
✓ Branch 2 taken 5927 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4441 times.
✓ Branch 5 taken 1486 times.
✓ Branch 6 taken 499 times.
✓ Branch 7 taken 690345 times.
✓ Branch 8 taken 1486 times.
✓ Branch 9 taken 690844 times.
692829 my_strcasecmp(table_alias_charset, table_name, tables->alias)) ||
9569
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 499 times.
499 (db_name && strcmp(tables->db, db_name)))
9570 1486 continue;
9571
9572 /*
9573 Ensure that we have access rights to all fields to be inserted. Under
9574 some circumstances, this check may be skipped.
9575
9576 - If any_privileges is true, skip the check.
9577
9578 - If the SELECT privilege has been found as fulfilled already,
9579 the check is skipped.
9580
9581 NOTE: This check is not sufficient: If a user has SELECT_ACL privileges
9582 for a view, it does not mean having the same privileges for the
9583 underlying tables/view. Thus, we have to perform individual column
9584 privilege checks below (or recurse down to all underlying tables here).
9585 */
9586
4/4
✓ Branch 0 taken 687719 times.
✓ Branch 1 taken 3125 times.
✓ Branch 2 taken 856 times.
✓ Branch 3 taken 686863 times.
690844 if (!any_privileges && !(tables->grant.privilege & SELECT_ACL)) {
9587
1/2
✓ Branch 0 taken 856 times.
✗ Branch 1 not taken.
856 field_iterator.set(tables);
9588
3/4
✓ Branch 0 taken 856 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✓ Branch 3 taken 839 times.
856 if (check_grant_all_columns(thd, SELECT_ACL, &field_iterator))
9589 17 return true;
9590 }
9591
9592 /*
9593 Update the tables used in the query based on the referenced fields. For
9594 views and natural joins this update is performed inside the loop below.
9595 */
9596
2/2
✓ Branch 0 taken 584789 times.
✓ Branch 1 taken 106038 times.
690827 if (table) {
9597 584789 thd->lex->current_query_block()->select_list_tables |= tables->map();
9598 }
9599
9600 /*
9601 Initialize a generic field iterator for the current table reference.
9602 Notice that it is guaranteed that this iterator will iterate over the
9603 fields of a single table reference, because 'tables' is a leaf (for
9604 name resolution purposes).
9605 */
9606
1/2
✓ Branch 0 taken 690827 times.
✗ Branch 1 not taken.
690827 field_iterator.set(tables);
9607
9608
4/6
✓ Branch 0 taken 4436281 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5127108 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 4436302 times.
✓ Branch 5 taken 690806 times.
5127108 for (; !field_iterator.end_of_fields(); field_iterator.next()) {
9609
1/2
✓ Branch 0 taken 4436302 times.
✗ Branch 1 not taken.
4436302 Item *const item = field_iterator.create_item(thd);
9610
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4436302 times.
4436323 if (!item) return true; /* purecov: inspected */
9611
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4436302 times.
4436302 assert(item->fixed);
9612
9613
3/4
✓ Branch 0 taken 4436302 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3328950 times.
✓ Branch 3 taken 1107352 times.
4436302 if (item->type() == Item::FIELD_ITEM) {
9614 3328950 Item_field *field = down_cast<Item_field *>(item);
9615 /*
9616 If the column is hidden from users and not used in USING clause of
9617 a join, do not add this column in place of '*'.
9618 */
9619
1/2
✓ Branch 0 taken 3328950 times.
✗ Branch 1 not taken.
3328950 bool is_hidden = field->field->is_hidden();
9620
2/2
✓ Branch 0 taken 894 times.
✓ Branch 1 taken 3328056 times.
3329844 is_hidden &= (tables->join_using_fields == nullptr ||
9621
3/4
✓ Branch 0 taken 894 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 338 times.
✓ Branch 3 taken 556 times.
894 !test_if_string_in_list(field->field_name,
9622 tables->join_using_fields));
9623
2/2
✓ Branch 0 taken 1264 times.
✓ Branch 1 taken 3327686 times.
3328950 if (is_hidden) continue;
9624
9625 /* cache the table for the Item_fields inserted by expanding stars */
9626
2/2
✓ Branch 0 taken 3326133 times.
✓ Branch 1 taken 1553 times.
3327686 if (tables->cacheable_table) field->cached_table = tables;
9627 }
9628
9629
2/2
✓ Branch 0 taken 681890 times.
✓ Branch 1 taken 3753148 times.
4435038 if (!found) {
9630 681890 found = true;
9631
1/2
✓ Branch 0 taken 681890 times.
✗ Branch 1 not taken.
681890 **it = item; /* Replace '*' with the first found item. */
9632 } else {
9633 /* Add 'item' to the SELECT list, after the current one. */
9634
2/4
✓ Branch 0 taken 3753148 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 3753148 times.
✗ Branch 3 not taken.
3753148 *it = fields->insert(*it + 1, item);
9635 }
9636
9637 /*
9638 Set privilege information for the fields of newly created views.
9639 We have that (any_priviliges == true) if and only if we are creating
9640 a view. In the time of view creation we can't use the MERGE algorithm,
9641 therefore if 'tables' is itself a view, it is represented by a
9642 temporary table. Thus in this case we can be sure that 'item' is an
9643 Item_field.
9644 */
9645
2/2
✓ Branch 0 taken 42541 times.
✓ Branch 1 taken 4392497 times.
4435038 if (any_privileges) {
9646
4/6
✓ Branch 0 taken 42541 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 42494 times.
✓ Branch 3 taken 47 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 47 times.
42541 assert((tables->field_translation == nullptr && table) ||
9647 tables->is_natural_join);
9648
2/4
✓ Branch 0 taken 42541 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 42541 times.
42541 assert(item->type() == Item::FIELD_ITEM);
9649 42541 Item_field *const fld = (Item_field *)item;
9650
1/2
✓ Branch 0 taken 42541 times.
✗ Branch 1 not taken.
42541 const char *field_table_name = field_iterator.get_table_name();
9651
6/6
✓ Branch 0 taken 42036 times.
✓ Branch 1 taken 505 times.
✓ Branch 2 taken 41963 times.
✓ Branch 3 taken 73 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 42540 times.
84504 if (!tables->schema_table && !tables->is_internal() &&
9652 41963 !(fld->have_privileges =
9653
3/6
✓ Branch 0 taken 41963 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 41963 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 41963 times.
✗ Branch 5 not taken.
41963 (get_column_grant(thd, field_iterator.grant(),
9654 field_iterator.get_db_name(),
9655
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 41962 times.
41963 field_table_name, fld->field_name) &
9656 VIEW_ANY_ACL))) {
9657
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), "ANY",
9658
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->security_context()->priv_user().str,
9659
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->security_context()->host_or_ip().str, field_table_name);
9660 1 return true;
9661 }
9662 }
9663
9664 8870074 thd->lex->current_query_block()->select_list_tables |=
9665
1/2
✓ Branch 0 taken 4435037 times.
✗ Branch 1 not taken.
4435037 item->used_tables();
9666
9667
1/2
✓ Branch 0 taken 4435037 times.
✗ Branch 1 not taken.
4435037 Field *const field = field_iterator.field();
9668
2/2
✓ Branch 0 taken 3327685 times.
✓ Branch 1 taken 1107352 times.
4435037 if (field) {
9669 // Register underlying fields in read map if wanted.
9670
1/2
✓ Branch 0 taken 3327685 times.
✗ Branch 1 not taken.
3327685 field->table->mark_column_used(field, thd->mark_used_columns);
9671 } else {
9672
6/6
✓ Branch 0 taken 1107237 times.
✓ Branch 1 taken 115 times.
✓ Branch 2 taken 1107144 times.
✓ Branch 3 taken 93 times.
✓ Branch 4 taken 1107144 times.
✓ Branch 5 taken 208 times.
1107352 if (thd->want_privilege && tables->is_view_or_derived()) {
9673
3/4
✓ Branch 0 taken 1107144 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 1107124 times.
1107144 if (item->walk(&Item::check_column_privileges, enum_walk::PREFIX,
9674 (uchar *)thd))
9675 20 return true;
9676 }
9677
9678 // Register underlying fields in read map if wanted.
9679 1107332 Mark_field mf(thd->mark_used_columns);
9680
1/2
✓ Branch 0 taken 1107332 times.
✗ Branch 1 not taken.
1107332 item->walk(&Item::mark_field_in_map, enum_walk::SUBQUERY_POSTFIX,
9681 (uchar *)&mf);
9682 }
9683 }
9684
3/3
✓ Branch 0 taken 690806 times.
✓ Branch 1 taken 1486 times.
✓ Branch 2 taken 38 times.
1384622 }
9685
2/2
✓ Branch 0 taken 681869 times.
✓ Branch 1 taken 15 times.
681884 if (found) return false;
9686
9687 /*
9688 TODO: in the case when we skipped all columns because there was a
9689 qualified '*', and all columns were coalesced, we have to give a more
9690 meaningful message than ER_BAD_TABLE_ERROR.
9691 */
9692
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
15 if (!table_name || !*table_name)
9693
1/2
✓ Branch 0 taken 13 times.
✗ Branch 1 not taken.
13 my_error(ER_NO_TABLES_USED, MYF(0));
9694 else {
9695 2 String tbl_name;
9696
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (db_name) {
9697
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 tbl_name.append(String(db_name, system_charset_info));
9698
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 tbl_name.append('.');
9699 }
9700
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 tbl_name.append(String(table_name, system_charset_info));
9701
9702
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
2 my_error(ER_BAD_TABLE_ERROR, MYF(0), tbl_name.c_ptr_safe());
9703 2 }
9704
9705 15 return true;
9706 681922 }
9707
9708 /******************************************************************************
9709 ** Fill a record with data (for INSERT or UPDATE)
9710 ** Returns : 1 if some field has wrong type
9711 ******************************************************************************/
9712
9713 /**
9714 Fill fields with given items.
9715
9716 @param thd Thread handler.
9717 @param table Table reference.
9718 @param fields Item_fields list to be filled
9719 @param values Values to fill with.
9720 @param bitmap Bitmap over fields to fill.
9721 @param insert_into_fields_bitmap Bitmap for fields that is set
9722 in fill_record.
9723 @param raise_autoinc_has_expl_non_null_val Set corresponding flag in TABLE
9724 object to true if non-NULL value
9725 is explicitly assigned to
9726 auto-increment field.
9727
9728 @note fill_record() may set TABLE::autoinc_field_has_explicit_non_null_value
9729 to true (even in case of failure!) and its caller should make sure that
9730 it is reset before next call to this function (i.e. before processing
9731 next row) and/or before TABLE instance is returned to table cache.
9732 One can use helper Auto_increment_field_not_null_reset_guard class
9733 to do this.
9734
9735 @note In order to simplify implementation this call is allowed to reset
9736 TABLE::autoinc_field_has_explicit_non_null_value flag even in case
9737 when raise_autoinc_has_expl_non_null_val is false. However, this
9738 should be fine since this flag is supposed to be reset already in
9739 such cases.
9740
9741 @return Operation status
9742 @retval false OK
9743 @retval true Error occurred
9744 */
9745
9746 56548001 bool fill_record(THD *thd, TABLE *table, const mem_root_deque<Item *> &fields,
9747 const mem_root_deque<Item *> &values, MY_BITMAP *bitmap,
9748 MY_BITMAP *insert_into_fields_bitmap,
9749 bool raise_autoinc_has_expl_non_null_val) {
9750
1/2
✓ Branch 0 taken 56549394 times.
✗ Branch 1 not taken.
56548001 DBUG_TRACE;
9751
9752
3/6
✓ Branch 0 taken 56549569 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56549617 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 56549617 times.
56549394 assert(CountVisibleFields(fields) == CountVisibleFields(values));
9753
9754 /*
9755 In case when TABLE object comes to fill_record() from Table Cache it
9756 should have autoinc_field_has_explicit_non_null_value flag set to false.
9757 In case when TABLE object comes to fill_record() after processing
9758 previous row this flag should be reset to false by caller.
9759
9760 Code which implements LOAD DATA is the exception to the above rule
9761 as it calls fill_record() to handle SET clause, after values for
9762 the columns directly coming from loaded from file are set and thus
9763 autoinc_field_has_explicit_non_null_value possibly set to true.
9764 */
9765
4/6
✓ Branch 0 taken 10032 times.
✓ Branch 1 taken 56539585 times.
✓ Branch 2 taken 10032 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10032 times.
✗ Branch 5 not taken.
56549617 assert(table->autoinc_field_has_explicit_non_null_value == false ||
9766 (raise_autoinc_has_expl_non_null_val &&
9767 thd->lex->sql_command == SQLCOM_LOAD));
9768
9769
2/4
✓ Branch 0 taken 56548636 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56549524 times.
✗ Branch 3 not taken.
56549617 auto value_it = VisibleFields(values).begin();
9770
8/14
✓ Branch 0 taken 56548767 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56549597 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56549607 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 119029796 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 119027019 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 175576687 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 119030946 times.
✓ Branch 13 taken 56545741 times.
175579601 for (Item *fld : VisibleFields(fields)) {
9771
1/2
✓ Branch 0 taken 119028724 times.
✗ Branch 1 not taken.
119029796 Item_field *const field = fld->field_for_view_update();
9772
2/4
✓ Branch 0 taken 119029467 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 119030254 times.
✗ Branch 3 not taken.
119028724 assert(field != nullptr && field->table_ref->table == table);
9773
9774 119030254 Field *const rfield = field->field;
9775
2/4
✓ Branch 0 taken 119031918 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 119032028 times.
✗ Branch 3 not taken.
119030254 Item *value = *value_it++;
9776
9777 /* If bitmap over wanted fields are set, skip non marked fields. */
9778
6/6
✓ Branch 0 taken 1035009 times.
✓ Branch 1 taken 117997019 times.
✓ Branch 2 taken 1008059 times.
✓ Branch 3 taken 26034 times.
✓ Branch 4 taken 1008059 times.
✓ Branch 5 taken 118023053 times.
119032028 if (bitmap && !bitmap_is_set(bitmap, rfield->field_index())) continue;
9779
9780 118023053 bitmap_set_bit(table->fields_set_during_insert, rfield->field_index());
9781
2/2
✓ Branch 0 taken 50559 times.
✓ Branch 1 taken 117970443 times.
118021002 if (insert_into_fields_bitmap)
9782 50559 bitmap_set_bit(insert_into_fields_bitmap, rfield->field_index());
9783
9784 /* Generated columns will be filled after all base columns are done. */
9785
2/2
✓ Branch 0 taken 3098 times.
✓ Branch 1 taken 118017490 times.
118021002 if (rfield->is_gcol()) continue;
9786
9787
2/2
✓ Branch 0 taken 113455752 times.
✓ Branch 1 taken 4561738 times.
118017490 if (raise_autoinc_has_expl_non_null_val &&
9788
2/2
✓ Branch 0 taken 1009088 times.
✓ Branch 1 taken 112446664 times.
113455752 rfield == table->next_number_field)
9789 1009088 table->autoinc_field_has_explicit_non_null_value = true;
9790 /*
9791 We handle errors from save_in_field() by first checking the return
9792 value and then testing thd->is_error(). thd->is_error() can be set
9793 even when save_in_field() does not return a negative value.
9794 @todo save_in_field returns an enum which should never be a negative
9795 value. We should change this test to check for correct enum value.
9796
9797 The below call can reset TABLE::autoinc_field_has_explicit_non_null_value
9798 flag depending on value provided (for details please see
9799 set_field_to_null_with_conversions()). So evaluation of this flag can't
9800 be moved outside of fill_record(), to be done once per statement.
9801 */
9802
2/4
✓ Branch 0 taken 118022891 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 118022891 times.
118017490 if (value->save_in_field(rfield, false) < 0) {
9803 my_error(ER_UNKNOWN_ERROR, MYF(0));
9804 4105 return true;
9805 }
9806
3/4
✓ Branch 0 taken 118023025 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4105 times.
✓ Branch 3 taken 118018920 times.
118022891 if (thd->is_error()) return true;
9807 }
9808
9809
4/4
✓ Branch 0 taken 332352 times.
✓ Branch 1 taken 56212672 times.
✓ Branch 2 taken 81 times.
✓ Branch 3 taken 56544959 times.
56878109 if (table->has_gcol() &&
9810
5/6
✓ Branch 0 taken 332332 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 332368 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 81 times.
✓ Branch 5 taken 332287 times.
332352 update_generated_write_fields(bitmap ? bitmap : table->write_set, table))
9811 81 return true;
9812
9813 /*
9814 TABLE::autoinc_field_has_explicit_non_null_value should not be set to
9815 true in raise_autoinc_has_expl_non_null_val == false mode.
9816 */
9817
3/4
✓ Branch 0 taken 597240 times.
✓ Branch 1 taken 55947719 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 597240 times.
56544959 assert(table->autoinc_field_has_explicit_non_null_value == false ||
9818 raise_autoinc_has_expl_non_null_val);
9819
9820
1/2
✓ Branch 0 taken 56545099 times.
✗ Branch 1 not taken.
56544959 return thd->is_error();
9821 56549285 }
9822
9823 /**
9824 Check the NOT NULL constraint on all the fields of the current record.
9825
9826 @param thd Thread context.
9827 @param fields Collection of fields.
9828
9829 @return Error status.
9830 */
9831 56474873 static bool check_record(THD *thd, const mem_root_deque<Item *> &fields) {
9832
8/14
✓ Branch 0 taken 56475517 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 56476099 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 56476220 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 117901616 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 117902121 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 174377305 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 117901229 times.
✓ Branch 13 taken 56476076 times.
174376300 for (Item *fld : VisibleFields(fields)) {
9833
1/2
✓ Branch 0 taken 117901842 times.
✗ Branch 1 not taken.
117901616 Item_field *field = fld->field_for_view_update();
9834
2/4
✓ Branch 0 taken 117902034 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 117901427 times.
235803461 if (field &&
9835
2/4
✓ Branch 0 taken 117901619 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 117901619 times.
117902034 field->field->check_constraints(ER_BAD_NULL_ERROR) != TYPE_OK) {
9836 my_error(ER_UNKNOWN_ERROR, MYF(0));
9837 return true;
9838 }
9839 }
9840 56476076 return thd->is_error();
9841 }
9842
9843 /**
9844 Check the NOT NULL constraint on all the fields of the current record.
9845
9846 @param thd Thread context.
9847 @param ptr Fields.
9848
9849 @return Error status.
9850 */
9851 183 bool check_record(THD *thd, Field **ptr) {
9852 Field *field;
9853
5/6
✓ Branch 0 taken 514 times.
✓ Branch 1 taken 183 times.
✓ Branch 2 taken 514 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 514 times.
✓ Branch 5 taken 183 times.
697 while ((field = *ptr++) && !thd->is_error()) {
9854
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 514 times.
514 if (field->check_constraints(ER_BAD_NULL_ERROR) != TYPE_OK) return true;
9855 }
9856 183 return thd->is_error();
9857 }
9858
9859 /**
9860 Check the NOT NULL constraint on all the fields explicitly set
9861 in INSERT INTO statement or implicitly set in BEFORE trigger.
9862
9863 @param thd Thread context.
9864 @param ptr Fields.
9865
9866 @return Error status.
9867 */
9868
9869 1986109 static bool check_inserting_record(THD *thd, Field **ptr) {
9870 Field *field;
9871
9872
5/6
✓ Branch 0 taken 11868888 times.
✓ Branch 1 taken 1986070 times.
✓ Branch 2 taken 11868888 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11868888 times.
✓ Branch 5 taken 1986070 times.
13854958 while ((field = *ptr++) && !thd->is_error()) {
9873 11868888 if (bitmap_is_set(field->table->fields_set_during_insert,
9874
4/4
✓ Branch 0 taken 11829134 times.
✓ Branch 1 taken 39754 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 11868849 times.
35566910 field->field_index()) &&
9875
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 11829095 times.
11829134 field->check_constraints(ER_BAD_NULL_ERROR) != TYPE_OK)
9876 39 return true;
9877 }
9878
9879 1986070 return thd->is_error();
9880 }
9881
9882 /**
9883 Invoke check constraints defined on the table.
9884
9885 @param thd Thread handle.
9886 @param table Instance of TABLE.
9887
9888 @retval false If all enforced check constraints are satisfied.
9889 @retval true Otherwise. THD::is_error() may be "true" in this case.
9890 */
9891
9892 62882675 bool invoke_table_check_constraints(THD *thd, const TABLE *table) {
9893
2/2
✓ Branch 0 taken 2014 times.
✓ Branch 1 taken 62880661 times.
62882675 if (table->table_check_constraint_list != nullptr) {
9894
2/2
✓ Branch 0 taken 3462 times.
✓ Branch 1 taken 1538 times.
5259 for (auto &table_cc : *table->table_check_constraint_list) {
9895
2/2
✓ Branch 0 taken 2027 times.
✓ Branch 1 taken 1435 times.
3462 if (table_cc.is_enforced()) {
9896 /*
9897 Invoke check constraints only if column(s) used by check constraint is
9898 updated.
9899 */
9900 6020 if ((thd->lex->sql_command == SQLCOM_UPDATE ||
9901
6/6
✓ Branch 0 taken 1963 times.
✓ Branch 1 taken 64 times.
✓ Branch 2 taken 7 times.
✓ Branch 3 taken 1956 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2026 times.
2099 thd->lex->sql_command == SQLCOM_UPDATE_MULTI) &&
9902
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 70 times.
72 !bitmap_is_overlapping(
9903 72 &table_cc.value_generator()->base_columns_map,
9904 71 table->write_set)) {
9905
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 DEBUG_SYNC(thd, "skip_check_constraints_on_unaffected_columns");
9906 2 continue;
9907 }
9908
9909 // Validate check constraint.
9910 2026 Item *check_const_expr_item = table_cc.value_generator()->expr_item;
9911 2026 check_const_expr_item->m_in_check_constraint_exec_ctx = true;
9912
2/2
✓ Branch 0 taken 1449 times.
✓ Branch 1 taken 577 times.
3475 bool is_constraint_violated = (!check_const_expr_item->val_bool() &&
9913
2/2
✓ Branch 0 taken 218 times.
✓ Branch 1 taken 1231 times.
1449 !check_const_expr_item->null_value);
9914 2026 check_const_expr_item->m_in_check_constraint_exec_ctx = false;
9915
9916 /*
9917 If check constraint is violated then report an error. If expression
9918 operand types are incompatible and reported error in conversion even
9919 then report a more user friendly error. Sql_conditions of DA still has
9920 a conversion(actual reported) error in the error stack.
9921 */
9922
5/6
✓ Branch 0 taken 1808 times.
✓ Branch 1 taken 218 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1808 times.
✓ Branch 4 taken 218 times.
✓ Branch 5 taken 1808 times.
2026 if (is_constraint_violated || thd->is_error()) {
9923
2/2
✓ Branch 0 taken 39 times.
✓ Branch 1 taken 179 times.
218 if (thd->is_error()) thd->clear_error();
9924 218 my_error(ER_CHECK_CONSTRAINT_VIOLATED, MYF(0), table_cc.name().str);
9925 218 return true;
9926 }
9927 }
9928 }
9929 }
9930
9931 62882199 return false;
9932 }
9933
9934 /**
9935 Check if SQL-statement is INSERT/INSERT SELECT/REPLACE/REPLACE SELECT
9936 and trigger event is ON INSERT. When this condition is true that means
9937 that the statement basically can invoke BEFORE INSERT trigger if it
9938 was created before.
9939
9940 @param event event type for triggers to be invoked
9941 @param sql_command Type of SQL statement
9942
9943 @return Test result
9944 @retval true SQL-statement is
9945 INSERT/INSERT SELECT/REPLACE/REPLACE SELECT
9946 and trigger event is ON INSERT
9947 @retval false Either SQL-statement is not
9948 INSERT/INSERT SELECT/REPLACE/REPLACE SELECT
9949 or trigger event is not ON INSERT
9950 */
9951 45504 static inline bool command_can_invoke_insert_triggers(
9952 enum enum_trigger_event_type event, enum_sql_command sql_command) {
9953 /*
9954 If it's 'INSERT INTO ... ON DUPLICATE KEY UPDATE ...' statement
9955 the event is TRG_EVENT_UPDATE and the SQL-command is SQLCOM_INSERT.
9956 */
9957
4/4
✓ Branch 0 taken 30511 times.
✓ Branch 1 taken 14993 times.
✓ Branch 2 taken 5821 times.
✓ Branch 3 taken 24690 times.
51325 return event == TRG_EVENT_INSERT &&
9958
4/4
✓ Branch 0 taken 339 times.
✓ Branch 1 taken 5482 times.
✓ Branch 2 taken 111 times.
✓ Branch 3 taken 228 times.
5821 (sql_command == SQLCOM_INSERT || sql_command == SQLCOM_INSERT_SELECT ||
9959
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 51 times.
111 sql_command == SQLCOM_REPLACE ||
9960 45504 sql_command == SQLCOM_REPLACE_SELECT);
9961 }
9962
9963 /**
9964 Execute BEFORE INSERT trigger.
9965
9966 @param thd thread context
9967 @param table TABLE-object holding list of triggers
9968 to be invoked
9969 @param event event type for triggers to be invoked
9970 @param insert_into_fields_bitmap Bitmap for fields that is set
9971 in fill_record
9972
9973 @return Operation status
9974 @retval false OK
9975 @retval true Error occurred
9976 */
9977 30457 inline bool call_before_insert_triggers(THD *thd, TABLE *table,
9978 enum enum_trigger_event_type event,
9979 MY_BITMAP *insert_into_fields_bitmap) {
9980
2/2
✓ Branch 0 taken 59010 times.
✓ Branch 1 taken 30457 times.
89467 for (Field **f = table->field; *f; ++f) {
9981
4/4
✓ Branch 0 taken 23529 times.
✓ Branch 1 taken 35481 times.
✓ Branch 2 taken 1286 times.
✓ Branch 3 taken 57724 times.
82539 if ((*f)->is_flag_set(NO_DEFAULT_VALUE_FLAG) &&
9982
2/2
✓ Branch 0 taken 1286 times.
✓ Branch 1 taken 22243 times.
23529 !bitmap_is_set(insert_into_fields_bitmap, (*f)->field_index())) {
9983 1286 (*f)->set_tmp_null();
9984 }
9985 }
9986
9987 30457 return table->triggers->process_triggers(thd, event, TRG_ACTION_BEFORE, true);
9988 }
9989
9990 /**
9991 Fill fields in list with values from the list of items and invoke
9992 before triggers.
9993
9994 @param thd Thread context.
9995 @param optype_info COPY_INFO structure used for
9996 default values handling.
9997 @param fields Item_fields list to be filled.
9998 @param values Values to fill with.
9999 @param table TABLE-object for the table.
10000 @param event Event type for triggers to be
10001 invoked.
10002 @param num_fields Number of fields in table.
10003 @param raise_autoinc_has_expl_non_null_val Set corresponding flag in
10004 TABLE to true if non-NULL
10005 value is explicitly assigned
10006 to auto-increment field.
10007 @param[out] is_row_changed Set to true if a row is
10008 changed after filling record
10009 and invoking before triggers
10010 for UPDATE operation.
10011 Otherwise set to false.
10012
10013 @note This function assumes that fields which values will be set and
10014 triggers to be invoked belong to the same table, and that
10015 TABLE::record[0] and record[1] buffers correspond to new and old
10016 versions of row respectively.
10017
10018 @note This call may set TABLE::autoinc_field_has_explicit_non_null_value to
10019 true (even in case of failure!) and its caller should make sure that
10020 it is reset appropriately (@sa fill_record()).
10021
10022 @return Operation status
10023 @retval false OK
10024 @retval true Error occurred
10025 */
10026
10027 56524654 bool fill_record_n_invoke_before_triggers(
10028 THD *thd, COPY_INFO *optype_info, const mem_root_deque<Item *> &fields,
10029 const mem_root_deque<Item *> &values, TABLE *table,
10030 enum enum_trigger_event_type event, int num_fields,
10031 bool raise_autoinc_has_expl_non_null_val, bool *is_row_changed) {
10032 // is_row_changed is used by UPDATE operation to set compare_record() result.
10033
3/4
✓ Branch 0 taken 4134042 times.
✓ Branch 1 taken 52390612 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4134080 times.
56524654 assert(is_row_changed == nullptr ||
10034 optype_info->get_operation_type() == COPY_INFO::UPDATE_OPERATION);
10035 /*
10036 Fill DEFAULT functions (like CURRENT_TIMESTAMP) and DEFAULT expressions on
10037 the columns that are not on the list of assigned columns.
10038 */
10039 127239916 auto fill_function_defaults = [table, optype_info, is_row_changed]() {
10040 /*
10041 Unlike INSERT and LOAD, UPDATE operation requires comparison of old
10042 and new records to determine whether function defaults have to be
10043 evaluated.
10044 */
10045
2/2
✓ Branch 0 taken 4133766 times.
✓ Branch 1 taken 52386939 times.
56520503 if (optype_info->get_operation_type() == COPY_INFO::UPDATE_OPERATION) {
10046 4133769 *is_row_changed =
10047
4/4
✓ Branch 0 taken 3993500 times.
✓ Branch 1 taken 140272 times.
✓ Branch 2 taken 3825048 times.
✓ Branch 3 taken 168449 times.
4133766 (!records_are_comparable(table) || compare_records(table));
10048 /*
10049 Evaluate function defaults for columns with ON UPDATE clause only
10050 if any other column of the row is updated.
10051 */
10052
4/4
✓ Branch 0 taken 3965320 times.
✓ Branch 1 taken 168449 times.
✓ Branch 2 taken 142000 times.
✓ Branch 3 taken 3991770 times.
8099090 if (*is_row_changed &&
10053
2/2
✓ Branch 0 taken 142000 times.
✓ Branch 1 taken 3823321 times.
3965320 (optype_info->function_defaults_apply_on_columns(table->write_set))) {
10054
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 142000 times.
142000 if (optype_info->set_function_defaults(table)) return true;
10055 }
10056
2/2
✓ Branch 0 taken 1964119 times.
✓ Branch 1 taken 50422815 times.
52386939 } else if (optype_info->function_defaults_apply_on_columns(
10057 table->write_set)) {
10058
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 1964430 times.
1964119 if (optype_info->set_function_defaults(table)) return true;
10059 }
10060 56521015 return false;
10061 56524692 };
10062
10063 /*
10064 If it's 'INSERT INTO ... ON DUPLICATE KEY UPDATE ...' statement
10065 the event is TRG_EVENT_UPDATE and the SQL-command is SQLCOM_INSERT.
10066 */
10067
10068 Trigger_chain *tc =
10069 56524692 table->triggers != nullptr
10070
2/2
✓ Branch 0 taken 57657 times.
✓ Branch 1 taken 56467035 times.
56524692 ? table->triggers->get_triggers(event, TRG_ACTION_BEFORE)
10071 56524810 : nullptr;
10072
10073
2/2
✓ Branch 0 taken 45504 times.
✓ Branch 1 taken 56479306 times.
56524810 if (tc != nullptr) {
10074 bool rc;
10075
10076
1/2
✓ Branch 0 taken 45504 times.
✗ Branch 1 not taken.
45504 table->triggers->enable_fields_temporary_nullability(thd);
10077
2/2
✓ Branch 0 taken 30460 times.
✓ Branch 1 taken 15044 times.
45504 if (command_can_invoke_insert_triggers(event, thd->lex->sql_command)) {
10078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30460 times.
30460 assert(num_fields);
10079
10080 30460 MY_BITMAP insert_into_fields_bitmap;
10081
1/2
✓ Branch 0 taken 30460 times.
✗ Branch 1 not taken.
30460 bitmap_init(&insert_into_fields_bitmap, nullptr, num_fields);
10082
10083
1/2
✓ Branch 0 taken 30460 times.
✗ Branch 1 not taken.
30460 rc = fill_function_defaults();
10084
10085
1/2
✓ Branch 0 taken 30460 times.
✗ Branch 1 not taken.
30460 if (!rc)
10086
1/2
✓ Branch 0 taken 30460 times.
✗ Branch 1 not taken.
30460 rc = fill_record(thd, table, fields, values, nullptr,
10087 &insert_into_fields_bitmap,
10088 raise_autoinc_has_expl_non_null_val);
10089
10090
2/2
✓ Branch 0 taken 30457 times.
✓ Branch 1 taken 3 times.
30460 if (!rc)
10091
1/2
✓ Branch 0 taken 30457 times.
✗ Branch 1 not taken.
30457 rc = call_before_insert_triggers(thd, table, event,
10092 &insert_into_fields_bitmap);
10093
10094
1/2
✓ Branch 0 taken 30460 times.
✗ Branch 1 not taken.
30460 bitmap_free(&insert_into_fields_bitmap);
10095 } else {
10096
1/2
✓ Branch 0 taken 15044 times.
✗ Branch 1 not taken.
15044 rc = fill_record(thd, table, fields, values, nullptr, nullptr,
10097 raise_autoinc_has_expl_non_null_val);
10098
10099
2/2
✓ Branch 0 taken 15043 times.
✓ Branch 1 taken 1 times.
15044 if (!rc) {
10100
1/2
✓ Branch 0 taken 15043 times.
✗ Branch 1 not taken.
15043 rc = fill_function_defaults();
10101
1/2
✓ Branch 0 taken 15043 times.
✗ Branch 1 not taken.
15043 if (!rc)
10102
1/2
✓ Branch 0 taken 15043 times.
✗ Branch 1 not taken.
15043 rc = table->triggers->process_triggers(thd, event, TRG_ACTION_BEFORE,
10103 true);
10104 // For UPDATE operation, check if row is updated by the triggers.
10105
2/2
✓ Branch 0 taken 14943 times.
✓ Branch 1 taken 49 times.
14992 if (!rc &&
10106
4/4
✓ Branch 0 taken 14992 times.
✓ Branch 1 taken 51 times.
✓ Branch 2 taken 54 times.
✓ Branch 3 taken 14989 times.
30035 optype_info->get_operation_type() == COPY_INFO::UPDATE_OPERATION &&
10107
2/2
✓ Branch 0 taken 54 times.
✓ Branch 1 taken 14889 times.
14943 !(*is_row_changed))
10108 54 *is_row_changed =
10109
5/8
✓ Branch 0 taken 54 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 54 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 54 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 5 times.
✓ Branch 7 taken 49 times.
54 (!records_are_comparable(table) || compare_records(table));
10110 }
10111 }
10112 /*
10113 Re-calculate generated fields to cater for cases when base columns are
10114 updated by the triggers.
10115 */
10116
2/4
✓ Branch 0 taken 45504 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 45504 times.
✗ Branch 3 not taken.
45504 assert(table->pos_in_table_list && !table->pos_in_table_list->is_view());
10117
6/6
✓ Branch 0 taken 45316 times.
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 45310 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 45498 times.
45510 if (!rc && table->has_gcol() &&
10118
2/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
6 tc->has_updated_trigger_fields(table->write_set)) {
10119 // Dont save old value while re-calculating generated fields.
10120 // Before image will already be saved in the first calculation.
10121
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 table->blobs_need_not_keep_old_value();
10122
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 rc = update_generated_write_fields(table->write_set, table);
10123 }
10124
10125
1/2
✓ Branch 0 taken 45504 times.
✗ Branch 1 not taken.
45504 table->triggers->disable_fields_temporary_nullability();
10126
10127
5/6
✓ Branch 0 taken 45316 times.
✓ Branch 1 taken 188 times.
✓ Branch 2 taken 45316 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 40 times.
✓ Branch 5 taken 45276 times.
45504 return rc || check_inserting_record(thd, table->field);
10128 } else {
10129
3/4
✓ Branch 0 taken 56479403 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4183 times.
✓ Branch 3 taken 56475220 times.
56479306 if (fill_record(thd, table, fields, values, nullptr, nullptr,
10130 raise_autoinc_has_expl_non_null_val))
10131 4183 return true;
10132
3/4
✓ Branch 0 taken 56475587 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 56475582 times.
56475220 if (fill_function_defaults()) return true;
10133
1/2
✓ Branch 0 taken 56476287 times.
✗ Branch 1 not taken.
56475582 return check_record(thd, fields);
10134 }
10135 }
10136
10137 /**
10138 Fill field buffer with values from Field list.
10139
10140 @param thd Thread handler.
10141 @param table Table reference.
10142 @param ptr Array of fields to fill in.
10143 @param values List of values to fill with.
10144 @param bitmap Bitmap over fields to fill.
10145 @param insert_into_fields_bitmap Bitmap for fields that is set
10146 in fill_record.
10147 @param raise_autoinc_has_expl_non_null_val Set corresponding flag in TABLE
10148 object to true if non-NULL value
10149 is explicitly assigned to
10150 auto-increment field.
10151
10152 @note fill_record() may set TABLE::autoinc_field_has_explicit_non_null_value
10153 to true (even in case of failure!) and its caller should make sure that
10154 it is reset before next call to this function (i.e. before processing
10155 next row) and/or before TABLE instance is returned to table cache.
10156 One can use helper Auto_increment_field_not_null_reset_guard class
10157 to do this.
10158
10159 @note In order to simplify implementation this call is allowed to reset
10160 TABLE::autoinc_field_has_explicit_non_null_value flag even in case
10161 when raise_autoinc_has_expl_non_null_val is false. However, this
10162 should be fine since this flag is supposed to be reset already in
10163 such cases.
10164
10165 @return Operation status
10166 @retval false OK
10167 @retval true Error occurred
10168 */
10169
10170 2524241 bool fill_record(THD *thd, TABLE *table, Field **ptr,
10171 const mem_root_deque<Item *> &values, MY_BITMAP *bitmap,
10172 MY_BITMAP *insert_into_fields_bitmap,
10173 bool raise_autoinc_has_expl_non_null_val) {
10174
1/2
✓ Branch 0 taken 2524241 times.
✗ Branch 1 not taken.
2524241 DBUG_TRACE;
10175
10176 /*
10177 In case when TABLE object comes to fill_record() from Table Cache it
10178 should have autoinc_field_has_explicit_non_null_value flag set to false.
10179 In case when TABLE object comes to fill_record() after processing
10180 previous row this flag should be reset to false by caller.
10181 */
10182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2524241 times.
2524241 assert(table->autoinc_field_has_explicit_non_null_value == false);
10183
10184 Field *field;
10185
2/4
✓ Branch 0 taken 2524241 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2524241 times.
✗ Branch 3 not taken.
2524241 auto value_it = VisibleFields(values).begin();
10186
6/8
✓ Branch 0 taken 12331477 times.
✓ Branch 1 taken 2524208 times.
✓ Branch 2 taken 12331477 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 12331477 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 12331477 times.
✓ Branch 7 taken 2524208 times.
14855685 while ((field = *ptr++) && !thd->is_error()) {
10187 // Skip hidden system field.
10188
3/4
✓ Branch 0 taken 12331477 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 12331476 times.
12331477 if (field->is_hidden_by_system()) continue;
10189
10190
2/4
✓ Branch 0 taken 12331476 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12331476 times.
✗ Branch 3 not taken.
12331476 Item *value = *value_it++;
10191
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12331476 times.
12331476 assert(field->table == table);
10192
10193 /* If bitmap over wanted fields are set, skip non marked fields. */
10194
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 12331476 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 12331476 times.
12331476 if (bitmap && !bitmap_is_set(bitmap, field->field_index())) continue;
10195
10196 /*
10197 fill_record could be called as part of multi update and therefore
10198 table->fields_set_during_insert could be NULL.
10199 */
10200
2/2
✓ Branch 0 taken 11734935 times.
✓ Branch 1 taken 596541 times.
12331476 if (table->fields_set_during_insert)
10201 11734935 bitmap_set_bit(table->fields_set_during_insert, field->field_index());
10202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12331476 times.
12331476 if (insert_into_fields_bitmap)
10203 bitmap_set_bit(insert_into_fields_bitmap, field->field_index());
10204
10205 /* Generated columns will be filled after all base columns are done. */
10206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 12331476 times.
12331476 if (field->is_gcol()) continue;
10207
10208
2/2
✓ Branch 0 taken 11734935 times.
✓ Branch 1 taken 596541 times.
12331476 if (raise_autoinc_has_expl_non_null_val &&
10209
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 11734904 times.
11734935 field == table->next_number_field)
10210 31 table->autoinc_field_has_explicit_non_null_value = true;
10211
10212 /*
10213 @todo We should evaluate what other return values from save_in_field()
10214 that should be treated as errors instead of checking thd->is_error().
10215
10216 The below call can reset TABLE::autoinc_field_has_explicit_non_null_value
10217 flag depending on value provided (for details please see
10218 set_field_to_null_with_conversions()). So evaluation of this flag can't
10219 be moved outside of fill_record(), to be done once per statement.
10220 */
10221
1/2
✓ Branch 0 taken 12331476 times.
✗ Branch 1 not taken.
12331476 if (value->save_in_field(field, false) ==
10222
3/4
✓ Branch 0 taken 12331476 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 12331443 times.
24662952 TYPE_ERR_NULL_CONSTRAINT_VIOLATION ||
10223
3/4
✓ Branch 0 taken 12331476 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 12331443 times.
12331476 thd->is_error())
10224 33 return true;
10225 }
10226
10227
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2524207 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2524208 times.
2524209 if (table->has_gcol() &&
10228
3/6
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 1 times.
1 update_generated_write_fields(bitmap ? bitmap : table->write_set, table))
10229 return true;
10230
10231
6/12
✓ Branch 0 taken 2524208 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2524208 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2524208 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2524208 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2524208 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2524208 times.
2524208 assert(thd->is_error() ||
10232 value_it == VisibleFields(values).end()); // No extra value!
10233
10234 /*
10235 TABLE::autoinc_field_has_explicit_non_null_value should not be set to
10236 true in raise_autoinc_has_expl_non_null_val == false mode.
10237 */
10238
3/4
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 2524177 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 31 times.
2524208 assert(table->autoinc_field_has_explicit_non_null_value == false ||
10239 raise_autoinc_has_expl_non_null_val);
10240
10241
1/2
✓ Branch 0 taken 2524208 times.
✗ Branch 1 not taken.
2524208 return thd->is_error();
10242 2524241 }
10243
10244 /**
10245 Fill fields in array with values from the list of items and invoke
10246 before triggers.
10247
10248 @param thd Thread context.
10249 @param ptr NULL-ended array of fields to be filled.
10250 @param values Values to fill with.
10251 @param table TABLE-object holding list of triggers to be invoked.
10252 @param event Event type for triggers to be invoked.
10253 @param num_fields Number of fields in table.
10254
10255 @note This function assumes that fields which values will be set and triggers
10256 to be invoked belong to the same table, and that TABLE::record[0] and
10257 record[1] buffers correspond to new and old versions of row
10258 respectively.
10259 @note This function is called during handling of statements INSERT/
10260 INSERT SELECT/CREATE SELECT. It means that the only trigger's type
10261 that can be invoked when this function is called is a BEFORE INSERT
10262 trigger so we don't need to make branching based on the result of
10263 execution function command_can_invoke_insert_triggers().
10264
10265 @note Unlike another version of fill_record_n_invoke_before_triggers() this
10266 call tries to set TABLE::autoinc_field_has_explicit_non_null_value to
10267 correct value unconditionally. So this flag can be set to true (even
10268 in case of failure!) and the caller should make sure that it is reset
10269 appropriately (@sa fill_record()).
10270
10271 @retval false OK
10272 @retval true Error occurred.
10273 */
10274
10275 1940809 bool fill_record_n_invoke_before_triggers(THD *thd, Field **ptr,
10276 const mem_root_deque<Item *> &values,
10277 TABLE *table,
10278 enum enum_trigger_event_type event,
10279 int num_fields) {
10280 bool rc;
10281 Trigger_chain *tc =
10282 1940809 table->triggers != nullptr
10283
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1940809 times.
1940809 ? table->triggers->get_triggers(event, TRG_ACTION_BEFORE)
10284 1940809 : nullptr;
10285
10286
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1940809 times.
1940809 if (tc != nullptr) {
10287 assert(command_can_invoke_insert_triggers(event, thd->lex->sql_command));
10288 assert(num_fields);
10289
10290 table->triggers->enable_fields_temporary_nullability(thd);
10291
10292 MY_BITMAP insert_into_fields_bitmap;
10293 bitmap_init(&insert_into_fields_bitmap, nullptr, num_fields);
10294
10295 rc = fill_record(thd, table, ptr, values, nullptr,
10296 &insert_into_fields_bitmap, true);
10297 if (!rc)
10298 rc = call_before_insert_triggers(thd, table, event,
10299 &insert_into_fields_bitmap);
10300
10301 /*
10302 Re-calculate generated fields to cater for cases when base columns are
10303 updated by the triggers.
10304 */
10305 if (!rc && *ptr) {
10306 TABLE *table_p = (*ptr)->table;
10307 if (table_p->has_gcol() &&
10308 tc->has_updated_trigger_fields(table_p->write_set)) {
10309 // Dont save old value while re-calculating generated fields.
10310 // Before image will already be saved in the first calculation.
10311 table_p->blobs_need_not_keep_old_value();
10312 rc = update_generated_write_fields(table_p->write_set, table_p);
10313 }
10314 }
10315 bitmap_free(&insert_into_fields_bitmap);
10316 table->triggers->disable_fields_temporary_nullability();
10317 } else
10318 1940809 rc = fill_record(thd, table, ptr, values, nullptr, nullptr, true);
10319
10320
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1940793 times.
1940809 if (rc) return true;
10321
10322 1940793 return check_inserting_record(thd, ptr);
10323 }
10324
10325 /**
10326 Drop all temporary tables which have been left from previous server run.
10327 Used on server start-up.
10328
10329 @return False on success, true on error.
10330 */
10331
10332 9416 bool mysql_rm_tmp_tables(void) {
10333 uint i, idx;
10334 char filePath[FN_REFLEN], *tmpdir;
10335 MY_DIR *dirp;
10336 FILEINFO *file;
10337 THD *thd;
10338 9416 List<LEX_STRING> files;
10339 9416 List_iterator<LEX_STRING> files_it;
10340 LEX_STRING *file_str;
10341 9416 bool result = true;
10342
1/2
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
9416 DBUG_TRACE;
10343
10344
3/6
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9416 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 9416 times.
9416 if (!(thd = new THD)) return true; /* purecov: inspected */
10345 9416 thd->thread_stack = (char *)&thd;
10346
1/2
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
9416 thd->store_globals();
10347
10348 9416 MEM_ROOT files_root(PSI_NOT_INSTRUMENTED, 32768);
10349
10350
2/2
✓ Branch 0 taken 9416 times.
✓ Branch 1 taken 9416 times.
18832 for (i = 0; i <= mysql_tmpdir_list.max; i++) {
10351 9416 tmpdir = mysql_tmpdir_list.list[i];
10352 /* See if the directory exists */
10353
2/4
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9416 times.
9416 if (!(dirp = my_dir(tmpdir, MYF(MY_WME | MY_DONT_SORT)))) continue;
10354
10355 /* Find all SQLxxx files in the directory. */
10356
10357
2/2
✓ Branch 0 taken 26246 times.
✓ Branch 1 taken 9416 times.
35662 for (idx = 0; idx < dirp->number_off_files; idx++) {
10358 26246 file = dirp->dir_entry + idx;
10359
10360 /* skipping . and .. */
10361
2/2
✓ Branch 0 taken 21091 times.
✓ Branch 1 taken 5155 times.
26246 if (file->name[0] == '.' &&
10362
5/6
✓ Branch 0 taken 11675 times.
✓ Branch 1 taken 9416 times.
✓ Branch 2 taken 9416 times.
✓ Branch 3 taken 2259 times.
✓ Branch 4 taken 9416 times.
✗ Branch 5 not taken.
21091 (!file->name[1] || (file->name[1] == '.' && !file->name[2])))
10363 18832 continue;
10364
10365
2/2
✓ Branch 0 taken 7401 times.
✓ Branch 1 taken 13 times.
7414 if (strlen(file->name) > tmp_file_prefix_length &&
10366
2/2
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 7363 times.
7401 !memcmp(file->name, tmp_file_prefix, tmp_file_prefix_length)) {
10367 38 size_t filePath_len = snprintf(filePath, sizeof(filePath), "%s%c%s",
10368 38 tmpdir, FN_LIBCHAR, file->name);
10369
1/2
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
38 file_str = make_lex_string_root(&files_root, filePath, filePath_len);
10370
10371
3/6
✓ Branch 0 taken 38 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 38 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 38 times.
38 if (file_str == nullptr || files.push_back(file_str, &files_root)) {
10372 /* purecov: begin inspected */
10373 my_dirend(dirp);
10374 goto err;
10375 /* purecov: end */
10376 }
10377 }
10378 }
10379
1/2
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
9416 my_dirend(dirp);
10380 }
10381
10382 /*
10383 Ask SEs to delete temporary tables.
10384 Pass list of SQLxxx files as a reference.
10385 */
10386
1/2
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
9416 result = ha_rm_tmp_tables(thd, &files);
10387
10388 /* Mimic old behavior, remove suspicious files if SE have not done this. */
10389 9416 files_it.init(files);
10390
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9416 times.
9416 while ((file_str = files_it++))
10391 (void)mysql_file_delete(key_file_misc, file_str->str, MYF(0));
10392
10393 9416 err:
10394
1/2
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
9416 files_root.Clear();
10395
1/2
✓ Branch 0 taken 9416 times.
✗ Branch 1 not taken.
9416 delete thd;
10396 9416 return result;
10397 9416 }
10398
10399 /*****************************************************************************
10400 unireg support functions
10401 *****************************************************************************/
10402
10403 /*
10404 free all unused tables
10405
10406 NOTE
10407 This is called by 'handle_manager' when one wants to periodicly flush
10408 all not used tables.
10409 */
10410
10411 1 void tdc_flush_unused_tables() {
10412 1 table_cache_manager.lock_all_and_tdc();
10413 1 table_cache_manager.free_all_unused_tables();
10414 1 table_cache_manager.unlock_all_and_tdc();
10415 1 }
10416
10417 /**
10418 Remove all or some (depending on parameter) instances of TABLE and
10419 TABLE_SHARE from the table definition cache.
10420
10421 @param thd Thread context
10422 @param remove_type Type of removal:
10423 TDC_RT_REMOVE_ALL - remove all TABLE instances and
10424 TABLE_SHARE instance. There
10425 should be no used TABLE objects
10426 and caller should have exclusive
10427 metadata lock on the table.
10428 TDC_RT_REMOVE_NOT_OWN - remove all TABLE instances
10429 except those that belong to
10430 this thread. There should be
10431 no TABLE objects used by other
10432 threads and caller should have
10433 exclusive metadata lock on the
10434 table.
10435 TDC_RT_REMOVE_UNUSED - remove all unused TABLE
10436 instances (if there are no
10437 used instances will also
10438 remove TABLE_SHARE).
10439 TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE -
10440 remove all TABLE instances
10441 except those that belong to
10442 this thread, but don't mark
10443 TABLE_SHARE as old. There
10444 should be no TABLE objects
10445 used by other threads and
10446 caller should have exclusive
10447 metadata lock on the table.
10448 TDC_RT_MARK_FOR_REOPEN - remove all unused TABLE
10449 instances, mark used TABLE
10450 instances as needing reopen.
10451 @param db Name of database
10452 @param table_name Name of table
10453 @param has_lock If true, LOCK_open is already acquired
10454
10455 @note It assumes that table instances are already not used by any
10456 (other) thread (this should be achieved by using meta-data locks).
10457 */
10458
10459 1834986 void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
10460 const char *db, const char *table_name, bool has_lock) {
10461 char key[MAX_DBKEY_LENGTH];
10462 size_t key_length;
10463
10464
2/2
✓ Branch 0 taken 1834690 times.
✓ Branch 1 taken 296 times.
1834986 if (!has_lock)
10465
1/2
✓ Branch 0 taken 1834690 times.
✗ Branch 1 not taken.
1834690 table_cache_manager.lock_all_and_tdc();
10466 else
10467
1/2
✓ Branch 0 taken 296 times.
✗ Branch 1 not taken.
296 table_cache_manager.assert_owner_all_and_tdc();
10468
10469 #ifdef WITH_WSREP
10470 /* if thd was BF aborted, exclusive locks are cancelled */
10471 #else
10472 assert(remove_type == TDC_RT_REMOVE_UNUSED ||
10473 thd->mdl_context.owns_equal_or_stronger_lock(
10474 MDL_key::TABLE, db, table_name, MDL_EXCLUSIVE));
10475 #endif /* WITH_WSREP */
10476
10477
1/2
✓ Branch 0 taken 1834986 times.
✗ Branch 1 not taken.
1834986 key_length = create_table_def_key(db, table_name, key);
10478
10479
2/4
✓ Branch 0 taken 1834986 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1834986 times.
✗ Branch 3 not taken.
1834986 auto it = table_def_cache->find(string(key, key_length));
10480
10481 // If the table has a shadow copy in a secondary storage engine, or
10482 // if we don't know if the table has a shadow copy, we must also
10483 // attempt to evict the secondary table from the cache.
10484 const bool remove_secondary =
10485
4/4
✓ Branch 0 taken 439867 times.
✓ Branch 1 taken 1395119 times.
✓ Branch 2 taken 254 times.
✓ Branch 3 taken 439613 times.
1834986 it == table_def_cache->end() || it->second->has_secondary_engine();
10486
10487 // Helper function that evicts the TABLE_SHARE pointed to by an iterator.
10488 3230359 auto remove_table = [&](Table_definition_cache::iterator my_it) {
10489
2/2
✓ Branch 0 taken 2790384 times.
✓ Branch 1 taken 439975 times.
3230359 if (my_it == table_def_cache->end()) return;
10490 439975 TABLE_SHARE *share = my_it->second.get();
10491 /*
10492 Since share->ref_count is incremented when a table share is opened
10493 in get_table_share(), before LOCK_open is temporarily released, it
10494 is sufficient to check this condition alone and ignore the
10495 share->m_open_in_progress flag.
10496
10497 Note that it is safe to call table_cache_manager.free_table() for
10498 shares with m_open_in_progress == true, since such shares don't
10499 have any TABLE objects associated.
10500 */
10501
2/2
✓ Branch 0 taken 347532 times.
✓ Branch 1 taken 92443 times.
439975 if (share->ref_count() > 0) {
10502 /*
10503 Set share's version to zero in order to ensure that it gets
10504 automatically deleted once it is no longer referenced.
10505
10506 Note that code in TABLE_SHARE::wait_for_old_version() assumes
10507 that marking share as old and removal of its unused tables
10508 and of the share itself from TDC happens atomically under
10509 protection of LOCK_open, or, putting it another way, that
10510 TDC does not contain old shares which don't have any tables
10511 used.
10512 */
10513
2/2
✓ Branch 0 taken 292300 times.
✓ Branch 1 taken 55232 times.
347532 if (remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE &&
10514
2/2
✓ Branch 0 taken 291703 times.
✓ Branch 1 taken 597 times.
292300 remove_type != TDC_RT_MARK_FOR_REOPEN)
10515 291703 share->clear_version();
10516 347532 table_cache_manager.free_table(thd, remove_type, share);
10517
1/2
✓ Branch 0 taken 92443 times.
✗ Branch 1 not taken.
92443 } else if (remove_type != TDC_RT_MARK_FOR_REOPEN) {
10518 // There are no TABLE objects associated, so just remove the
10519 // share immediately. (Assert: When called with
10520 // TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE, there should always be a
10521 // TABLE object associated with the primary TABLE_SHARE.)
10522
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 92437 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
92443 assert(remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE ||
10523 share->is_secondary_engine());
10524
1/2
✓ Branch 0 taken 92443 times.
✗ Branch 1 not taken.
92443 table_def_cache->erase(to_string(share->table_cache_key));
10525 }
10526 1834986 };
10527
10528
1/2
✓ Branch 0 taken 1834986 times.
✗ Branch 1 not taken.
1834986 remove_table(it);
10529
10530
2/2
✓ Branch 0 taken 1395373 times.
✓ Branch 1 taken 439613 times.
1834986 if (remove_secondary)
10531
2/4
✓ Branch 0 taken 1395373 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1395373 times.
✗ Branch 3 not taken.
1395373 remove_table(
10532
1/2
✓ Branch 0 taken 1395373 times.
✗ Branch 1 not taken.
2790746 table_def_cache->find(create_table_def_key_secondary(db, table_name)));
10533
10534
3/4
✓ Branch 0 taken 1834690 times.
✓ Branch 1 taken 296 times.
✓ Branch 2 taken 1834690 times.
✗ Branch 3 not taken.
1834986 if (!has_lock) table_cache_manager.unlock_all_and_tdc();
10535 1834986 }
10536
10537 2548 int setup_ftfuncs(const THD *thd, Query_block *query_block) {
10538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2548 times.
2548 assert(query_block->has_ft_funcs());
10539
10540
1/2
✓ Branch 0 taken 2548 times.
✗ Branch 1 not taken.
2548 List_iterator<Item_func_match> li(*(query_block->ftfunc_list)),
10541
1/2
✓ Branch 0 taken 2548 times.
✗ Branch 1 not taken.
2548 lj(*(query_block->ftfunc_list));
10542 Item_func_match *ftf, *ftf2;
10543
10544
2/2
✓ Branch 0 taken 2699 times.
✓ Branch 1 taken 2514 times.
5213 while ((ftf = li++)) {
10545
6/8
✓ Branch 0 taken 2699 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2699 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 2665 times.
✓ Branch 6 taken 34 times.
✓ Branch 7 taken 2665 times.
2699 if (ftf->table_ref && ftf->fix_index(thd)) return 1;
10546 2665 lj.rewind();
10547
10548 /*
10549 Notice that expressions added late (e.g. in ORDER BY) may be deleted
10550 during resolving. It is therefore important that an "early" expression
10551 is used as master for a "late" one, and not the other way around.
10552 */
10553
2/2
✓ Branch 0 taken 178 times.
✓ Branch 1 taken 2665 times.
2843 while ((ftf2 = lj++) != ftf) {
10554
7/8
✓ Branch 0 taken 178 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 105 times.
✓ Branch 3 taken 73 times.
✓ Branch 4 taken 95 times.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 95 times.
✓ Branch 7 taken 83 times.
178 if (ftf->eq(ftf2, true) && !ftf->master) ftf2->set_master(ftf);
10555 }
10556 }
10557
10558 2514 return 0;
10559 }
10560
10561 2469 bool init_ftfuncs(THD *thd, Query_block *query_block) {
10562
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2469 times.
2469 assert(query_block->has_ft_funcs());
10563
10564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2469 times.
2469 DBUG_PRINT("info", ("Performing FULLTEXT search"));
10565 2469 THD_STAGE_INFO(thd, stage_fulltext_initialization);
10566
10567
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2455 times.
2469 if (thd->lex->using_hypergraph_optimizer) {
10568 // Set the no_ranking hint if ranking of the results is not required. The
10569 // old optimizer does this when it determines which scan to use. The
10570 // hypergraph optimizer doesn't know until the full plan is built, so do it
10571 // here, just before the full-text search is performed.
10572
5/8
✓ Branch 0 taken 14 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 34 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 14 times.
34 for (Item_func_match &ifm : *query_block->ftfunc_list) {
10573
4/6
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 15 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 20 times.
20 if (ifm.master == nullptr && ifm.can_skip_ranking()) {
10574 ifm.get_hints()->set_hint_flag(FT_NO_RANKING);
10575 }
10576 }
10577 }
10578
10579
5/8
✓ Branch 0 taken 2469 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2469 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 5078 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2615 times.
✓ Branch 7 taken 2463 times.
5078 for (Item_func_match &ifm : *query_block->ftfunc_list) {
10580
3/4
✓ Branch 0 taken 2615 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 2609 times.
2615 if (ifm.init_search(thd)) {
10581 6 return true;
10582 }
10583 }
10584
10585 2463 return false;
10586 }
10587
10588 21 bool is_equal(const LEX_CSTRING *a, const LEX_CSTRING *b) noexcept {
10589
4/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 14 times.
✓ Branch 3 taken 2 times.
21 return a->length == b->length && !strncmp(a->str, b->str, a->length);
10590 }
10591
10592 621 static bool is_cond_equal(const Item *cond) noexcept {
10593
1/2
✓ Branch 0 taken 621 times.
✗ Branch 1 not taken.
1242 return (cond->type() == Item::FUNC_ITEM &&
10594
2/2
✓ Branch 0 taken 506 times.
✓ Branch 1 taken 115 times.
621 (((const Item_func *)cond)->functype() == Item_func::EQ_FUNC ||
10595
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 506 times.
1127 ((const Item_func *)cond)->functype() == Item_func::EQUAL_FUNC));
10596 }
10597
10598 506 static bool is_cond_mult_equal(const Item *cond) noexcept {
10599
1/2
✓ Branch 0 taken 506 times.
✗ Branch 1 not taken.
1012 return (cond->type() == Item::FUNC_ITEM &&
10600
2/2
✓ Branch 0 taken 463 times.
✓ Branch 1 taken 43 times.
1012 (((const Item_func *)cond)->functype() == Item_func::MULT_EQUAL_FUNC));
10601 }
10602
10603 /*
10604 And-or graph truth propagation algorithm is used to calculate if the
10605 statement is ordered or not.
10606
10607 Nodes:
10608 Join_node - And node, this is the root, successors are a list of
10609 Const_ordered_table_node.
10610 Const_ordered_table_node - Or node, have two Table_node as successors,
10611 one for ordered table, and the other for constant table.
10612 Table_node - Or node, have a list of Key_node and one All_columns_node
10613 as successors.
10614 Key_node - And node, successors are a list of Column_node that corresponding
10615 to the fields of the key.
10616 All_columns_node - And node, successors are a list of Column_node of all
10617 fields of the table.
10618 Column_node - Or node, represent a field of the table, it will take a
10619 Table_node as a successor, which means if a table is true
10620 (const or ordered), the all its columns are const or ordered.
10621 Successors to other column nodes will be added mutually if
10622 there is an equation to that field in the condition. The
10623 column nodes for fields that are in the ORDER BY or are
10624 equal to constants are added to the init_nodes of the Join_node,
10625 which is used as the initial true values of the propagation.
10626 */
10627
10628 /*
10629 Abstract base class for and-or node.
10630 */
10631 class Node {
10632 public:
10633 23001 Node() noexcept : todo(0) {}
10634 1646 virtual ~Node() {}
10635 virtual void add_successor(Node *node) = 0;
10636 /* Number of successors need to be true to make this node true. */
10637 uint todo;
10638 /* List of nodes that this node is a successor */
10639 List<Node> predecessors;
10640 };
10641
10642 /*
10643 Or node will be true if any of its successors is true.
10644 */
10645 class Or_node : public Node {
10646 public:
10647 14266 Or_node() noexcept : Node() {}
10648 22602 void add_successor(Node *node) override {
10649 22602 todo = 1;
10650 22602 node->predecessors.push_back(this);
10651 22602 }
10652 };
10653
10654 /*
10655 And node can only be true if all its successors are true.
10656 */
10657 class And_node : public Node {
10658 public:
10659 8735 And_node() noexcept : Node() {}
10660 11606 void add_successor(Node *node) override {
10661 11606 todo++;
10662 11606 node->predecessors.push_back(this);
10663 11606 }
10664 };
10665
10666 typedef Or_node Column_node;
10667 typedef And_node Key_node;
10668 typedef And_node All_columns_node;
10669
10670 class Table_node final : public Or_node {
10671 public:
10672 Table_node(const TABLE *table_arg);
10673 Column_node *get_column_node(const Field *field) const noexcept;
10674 Column_node *create_column_node(const Field *field);
10675 All_columns_node *create_all_columns_node();
10676 Key_node *create_key_node(const KEY *key_info);
10677
10678 private:
10679 const TABLE *table;
10680 Column_node **columns;
10681 };
10682
10683 2224 Table_node::Table_node(const TABLE *table_arg)
10684 2224 : table(table_arg),
10685 6672 columns((Column_node **)(*THR_MALLOC)
10686
2/4
✓ Branch 0 taken 2224 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2224 times.
✗ Branch 3 not taken.
2224 ->Alloc(sizeof(Column_node *) * table->s->fields)) {
10687 2224 memset(columns, 0, sizeof(Column_node *) * table->s->fields);
10688
10689
2/2
✓ Branch 0 taken 624 times.
✓ Branch 1 taken 1600 times.
2224 if (table->s->primary_key == MAX_KEY) {
10690
2/4
✓ Branch 0 taken 624 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 624 times.
✗ Branch 3 not taken.
624 add_successor(create_all_columns_node());
10691 624 return;
10692 }
10693 uint key;
10694
2/2
✓ Branch 0 taken 8846 times.
✓ Branch 1 taken 1600 times.
10446 for (key = 0; key < table->s->keys; key++) {
10695
2/2
✓ Branch 0 taken 7288 times.
✓ Branch 1 taken 1558 times.
8846 if ((table->s->key_info[key].flags & (HA_NOSAME | HA_NULL_PART_KEY)) ==
10696 HA_NOSAME)
10697
2/4
✓ Branch 0 taken 7288 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 7288 times.
✗ Branch 3 not taken.
7288 add_successor(create_key_node(&table->s->key_info[key]));
10698 }
10699 }
10700
10701 25948 inline Column_node *Table_node::get_column_node(const Field *field) const
10702 noexcept {
10703 25948 return columns[field->field_index()];
10704 }
10705
10706 12974 inline Column_node *Table_node::create_column_node(const Field *field) {
10707
2/2
✓ Branch 0 taken 10930 times.
✓ Branch 1 taken 2044 times.
12974 if (!get_column_node(field)) {
10708
1/2
✓ Branch 0 taken 10930 times.
✗ Branch 1 not taken.
10930 Column_node *column = new (*THR_MALLOC) Column_node;
10709 10930 columns[field->field_index()] = column;
10710 /*
10711 If the table is ORDERED or CONST, then all the columns are
10712 ORDERED or CONST, so add the table as an successor of the column
10713 node (Or_node).
10714 */
10715 10930 column->add_successor(this);
10716 }
10717 12974 return get_column_node(field);
10718 }
10719
10720 624 All_columns_node *Table_node::create_all_columns_node() {
10721
1/2
✓ Branch 0 taken 624 times.
✗ Branch 1 not taken.
624 All_columns_node *node = new (*THR_MALLOC) All_columns_node;
10722 624 uint i = 0;
10723
2/2
✓ Branch 0 taken 1608 times.
✓ Branch 1 taken 624 times.
2232 for (i = 0; i < table->s->fields; i++) {
10724 1608 Column_node *column = create_column_node(table->field[i]);
10725 1608 node->add_successor(column);
10726 }
10727 624 return node;
10728 }
10729
10730 7288 Key_node *Table_node::create_key_node(const KEY *key_info) {
10731
1/2
✓ Branch 0 taken 7288 times.
✗ Branch 1 not taken.
7288 Key_node *node = new (*THR_MALLOC) Key_node;
10732 7288 uint key_parts = key_info->user_defined_key_parts;
10733 uint i;
10734
2/2
✓ Branch 0 taken 8886 times.
✓ Branch 1 taken 7288 times.
16174 for (i = 0; i < key_parts; i++) {
10735 8886 KEY_PART_INFO *key_part = &key_info->key_part[i];
10736 8886 Field *field = table->field[key_part->fieldnr - 1];
10737 8886 node->add_successor(create_column_node(field));
10738 }
10739 7288 return node;
10740 }
10741
10742 class Const_ordered_table_node final : public Or_node {
10743 public:
10744 Const_ordered_table_node(const TABLE *table_arg);
10745 4661 const TABLE *get_table() const noexcept { return table; }
10746 Column_node *get_ordered_column_node(const Field *field) const;
10747 Column_node *get_const_column_node(const Field *field) const;
10748
10749 private:
10750 const TABLE *table;
10751 Table_node *ordered_table_node;
10752 Table_node *const_table_node;
10753 };
10754
10755 1112 Const_ordered_table_node::Const_ordered_table_node(const TABLE *table_arg)
10756 1112 : table(table_arg),
10757
2/4
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
1112 ordered_table_node(new (*THR_MALLOC) Table_node(table)),
10758
4/8
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1112 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1112 times.
✗ Branch 7 not taken.
2224 const_table_node(new (*THR_MALLOC) Table_node(table)) {
10759
1/2
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
1112 add_successor(ordered_table_node);
10760
1/2
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
1112 add_successor(const_table_node);
10761 1112 }
10762
10763 1485 inline Column_node *Const_ordered_table_node::get_ordered_column_node(
10764 const Field *field) const {
10765 1485 return ordered_table_node->create_column_node(field);
10766 }
10767
10768 995 inline Column_node *Const_ordered_table_node::get_const_column_node(
10769 const Field *field) const {
10770 995 return const_table_node->create_column_node(field);
10771 }
10772
10773 class Join_node : public And_node {
10774 public:
10775 Join_node(const mem_root_deque<TABLE_LIST *> *join_list, Item *cond,
10776 const ORDER *order);
10777 Join_node(const TABLE_LIST *table, Item *cond, const ORDER *order);
10778 bool is_ordered() const;
10779
10780 private:
10781 void add_join_list(const mem_root_deque<TABLE_LIST *> *join_list);
10782 Const_ordered_table_node *add_table(const TABLE *table);
10783 Const_ordered_table_node *get_const_ordered_table_node(const TABLE *table);
10784 Column_node *get_ordered_column_node(const Field *field);
10785 Column_node *get_const_column_node(const Field *field);
10786 void add_ordered_columns(const ORDER *order);
10787 void add_const_equi_columns(Item *cond);
10788 void add_const_column(const Field *field);
10789 void add_equi_column(const Field *left, const Field *right);
10790 bool field_belongs_to_tables(const Field *field) noexcept;
10791 List<Const_ordered_table_node> tables;
10792 List<Node> init_nodes;
10793 ulong max_sort_length;
10794 };
10795
10796 705 inline void Join_node::add_join_list(
10797 const mem_root_deque<TABLE_LIST *> *join_list) {
10798 705 Item *join_cond = join_list->front()->join_cond();
10799
7/12
✓ Branch 0 taken 705 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 705 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 994 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 994 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1699 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 994 times.
✓ Branch 11 taken 705 times.
1699 for (auto table : *join_list)
10800
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 983 times.
994 if (table->nested_join)
10801
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 add_join_list(&table->nested_join->join_list);
10802 else
10803
1/2
✓ Branch 0 taken 983 times.
✗ Branch 1 not taken.
983 add_table(table->table);
10804 705 add_const_equi_columns(join_cond);
10805 705 }
10806
10807 1112 inline Const_ordered_table_node *Join_node::add_table(const TABLE *table) {
10808 Const_ordered_table_node *tableNode =
10809
2/4
✓ Branch 0 taken 1112 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1112 times.
✗ Branch 3 not taken.
1112 new (*THR_MALLOC) Const_ordered_table_node(table);
10810 1112 add_successor(tableNode);
10811 1112 tables.push_back(tableNode);
10812 1112 return tableNode;
10813 }
10814
10815 693 inline Join_node::Join_node(const mem_root_deque<TABLE_LIST *> *join_list,
10816 693 Item *cond, const ORDER *order) {
10817
2/4
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 693 times.
693 assert(!join_list->empty());
10818
1/2
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
693 max_sort_length = current_thd->variables.max_sort_length;
10819
1/2
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
693 add_join_list(join_list);
10820
1/2
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
693 add_ordered_columns(order);
10821
1/2
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
693 add_const_equi_columns(cond);
10822 693 }
10823
10824 130 inline Join_node::Join_node(const TABLE_LIST *table, Item *cond,
10825 130 const ORDER *order) {
10826
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 max_sort_length = current_thd->variables.max_sort_length;
10827
2/2
✓ Branch 0 taken 129 times.
✓ Branch 1 taken 1 times.
130 if (table->table) {
10828
1/2
✓ Branch 0 taken 129 times.
✗ Branch 1 not taken.
129 add_table(table->table);
10829 } else {
10830
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 add_join_list(table->view_tables);
10831 }
10832
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 add_ordered_columns(order);
10833
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 add_const_equi_columns(cond);
10834 130 }
10835
10836 2480 inline Const_ordered_table_node *Join_node::get_const_ordered_table_node(
10837 const TABLE *table) {
10838
1/2
✓ Branch 0 taken 2480 times.
✗ Branch 1 not taken.
2480 List_iterator<Const_ordered_table_node> it(tables);
10839 Const_ordered_table_node *node;
10840
1/2
✓ Branch 0 taken 4500 times.
✗ Branch 1 not taken.
4500 while ((node = it++)) {
10841
2/2
✓ Branch 0 taken 2480 times.
✓ Branch 1 taken 2020 times.
4500 if (node->get_table() == table) return node;
10842 }
10843 assert(0);
10844 return add_table(table);
10845 }
10846
10847 138 inline bool Join_node::field_belongs_to_tables(const Field *field) noexcept {
10848 138 List_iterator<Const_ordered_table_node> it(tables);
10849 Const_ordered_table_node *node;
10850
1/2
✓ Branch 0 taken 161 times.
✗ Branch 1 not taken.
161 while ((node = it++)) {
10851
2/2
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 23 times.
161 if (node->get_table() == field->table) return true;
10852 }
10853 return false;
10854 }
10855
10856 1485 inline Column_node *Join_node::get_ordered_column_node(const Field *field) {
10857 1485 return get_const_ordered_table_node(field->table)
10858 1485 ->get_ordered_column_node(field);
10859 }
10860
10861 995 inline Column_node *Join_node::get_const_column_node(const Field *field) {
10862 995 return get_const_ordered_table_node(field->table)
10863 995 ->get_const_column_node(field);
10864 }
10865
10866 227 inline void Join_node::add_const_column(const Field *field) {
10867 227 Column_node *column = get_const_column_node(field);
10868 227 init_nodes.push_back(column);
10869 227 }
10870
10871 384 void Join_node::add_equi_column(const Field *left, const Field *right) {
10872 384 Column_node *left_column = get_const_column_node(left);
10873 384 Column_node *right_column = get_const_column_node(right);
10874 384 left_column->add_successor(right_column);
10875 384 right_column->add_successor(left_column);
10876
10877 384 left_column = get_ordered_column_node(left);
10878 384 right_column = get_ordered_column_node(right);
10879 384 left_column->add_successor(right_column);
10880 384 right_column->add_successor(left_column);
10881 384 }
10882
10883 696 inline bool is_cond_or(const Item *item) noexcept {
10884
2/2
✓ Branch 0 taken 621 times.
✓ Branch 1 taken 75 times.
696 if (item->type() != Item::COND_ITEM) return false;
10885
10886 75 const Item_cond *cond_item = (const Item_cond *)item;
10887 75 return (cond_item->functype() == Item_func::COND_OR_FUNC);
10888 }
10889
10890 696 static bool is_cond_and(const Item *item) noexcept {
10891
2/2
✓ Branch 0 taken 621 times.
✓ Branch 1 taken 75 times.
696 if (item->type() != Item::COND_ITEM) return false;
10892
10893 75 const Item_cond *cond_item = (const Item_cond *)item;
10894 75 return (cond_item->functype() == Item_func::COND_AND_FUNC);
10895 }
10896
10897 1827 void Join_node::add_const_equi_columns(Item *cond) {
10898
2/2
✓ Branch 0 taken 1131 times.
✓ Branch 1 taken 696 times.
1827 if (!cond) return;
10899
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 696 times.
696 if (is_cond_or(cond)) return;
10900
2/2
✓ Branch 0 taken 75 times.
✓ Branch 1 taken 621 times.
696 if (is_cond_and(cond)) {
10901 75 const List<Item> *args = ((const Item_cond *)cond)->argument_list();
10902
1/2
✓ Branch 0 taken 75 times.
✗ Branch 1 not taken.
75 List_iterator<Item> it(*const_cast<List<Item>*>(args));
10903 Item *c;
10904
3/4
✓ Branch 0 taken 299 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 299 times.
✓ Branch 3 taken 75 times.
374 while ((c = it++)) add_const_equi_columns(c);
10905 75 return;
10906 }
10907
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 506 times.
621 if (is_cond_equal(cond)) {
10908 uint i;
10909 115 Field *first_field = nullptr;
10910 115 Field *second_field = nullptr;
10911 115 Item **args = ((const Item_func *)cond)->arguments();
10912 115 uint arg_count = ((const Item_func *)cond)->argument_count();
10913 115 bool const_value = false;
10914
10915
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 115 times.
115 assert(arg_count == 2);
10916
10917 115 bool variable_field = false;
10918
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 115 times.
345 for (i = 0; i < arg_count; i++) {
10919
5/6
✓ Branch 0 taken 138 times.
✓ Branch 1 taken 92 times.
✓ Branch 2 taken 138 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 138 times.
✓ Branch 5 taken 92 times.
368 if (args[i]->real_item()->type() == Item::FIELD_ITEM &&
10920 138 (variable_field = field_belongs_to_tables(
10921 138 ((Item_field *)args[i]->real_item())->field))) {
10922
2/2
✓ Branch 0 taken 115 times.
✓ Branch 1 taken 23 times.
138 if (!first_field)
10923 115 first_field = ((const Item_field *)args[i]->real_item())->field;
10924 else
10925 23 second_field = ((const Item_field *)args[i]->real_item())->field;
10926
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 92 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 92 times.
✗ Branch 5 not taken.
92 } else if (args[i]->real_item()->basic_const_item() || !variable_field) {
10927 92 const_value = true;
10928 }
10929 }
10930
3/4
✓ Branch 0 taken 115 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 92 times.
✓ Branch 3 taken 23 times.
115 if (first_field && const_value)
10931 92 add_const_column(first_field);
10932
1/2
✓ Branch 0 taken 23 times.
✗ Branch 1 not taken.
23 else if (second_field)
10933 23 add_equi_column(first_field, second_field);
10934 115 return;
10935 }
10936
2/2
✓ Branch 0 taken 463 times.
✓ Branch 1 taken 43 times.
506 if (is_cond_mult_equal(cond)) {
10937 463 auto equal = down_cast<Item_equal *>(cond);
10938
10939
2/2
✓ Branch 0 taken 135 times.
✓ Branch 1 taken 328 times.
463 if (equal->get_const()) {
10940
5/8
✓ Branch 0 taken 135 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 135 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 270 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 135 times.
✓ Branch 7 taken 135 times.
270 for (Item_field &field : equal->get_fields()) {
10941
1/2
✓ Branch 0 taken 135 times.
✗ Branch 1 not taken.
135 add_const_column(field.field);
10942 }
10943 } else {
10944
1/2
✓ Branch 0 taken 328 times.
✗ Branch 1 not taken.
328 auto it = equal->get_fields().begin();
10945 328 Item_field& first_item = *it++;
10946
4/6
✓ Branch 0 taken 689 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 689 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 361 times.
✓ Branch 5 taken 328 times.
689 for (; it != equal->get_fields().end(); ++it) {
10947
1/2
✓ Branch 0 taken 361 times.
✗ Branch 1 not taken.
361 add_equi_column(first_item.field, it->field);
10948 }
10949 }
10950 }
10951 506 return;
10952 }
10953
10954 823 void Join_node::add_ordered_columns(const ORDER *order) {
10955
2/2
✓ Branch 0 taken 764 times.
✓ Branch 1 taken 823 times.
1587 for (; order; order = order->next) {
10956
2/2
✓ Branch 0 taken 758 times.
✓ Branch 1 taken 6 times.
764 if ((*order->item)->real_item()->type() == Item::FIELD_ITEM) {
10957 758 Field *field = ((Item_field *)(*order->item)->real_item())->field;
10958 /*
10959 If the field length is larger than the max_sort_length, then
10960 ORDER BY the field will not be guaranteed to be deterministic.
10961 */
10962
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 717 times.
758 if (field->field_length > max_sort_length) continue;
10963 717 Column_node *column = get_ordered_column_node(field);
10964 717 init_nodes.push_back(column);
10965 }
10966 }
10967 823 }
10968
10969 823 bool Join_node::is_ordered() const {
10970 823 List<Node> nodes(init_nodes);
10971
1/2
✓ Branch 0 taken 823 times.
✗ Branch 1 not taken.
823 List_iterator<Node> it(nodes);
10972 Node *node;
10973
10974
2/2
✓ Branch 0 taken 7937 times.
✓ Branch 1 taken 470 times.
8407 while ((node = it++)) {
10975 7937 node->todo--;
10976
2/2
✓ Branch 0 taken 7129 times.
✓ Branch 1 taken 808 times.
7937 if (node->todo == 0) {
10977
2/2
✓ Branch 0 taken 353 times.
✓ Branch 1 taken 6776 times.
7129 if (node == this) return true;
10978
1/2
✓ Branch 0 taken 6776 times.
✗ Branch 1 not taken.
6776 List_iterator<Node> pit(node->predecessors);
10979 Node *pnode;
10980
2/2
✓ Branch 0 taken 10035 times.
✓ Branch 1 taken 6776 times.
16811 while ((pnode = pit++)) {
10981
3/4
✓ Branch 0 taken 7260 times.
✓ Branch 1 taken 2775 times.
✓ Branch 2 taken 7260 times.
✗ Branch 3 not taken.
10035 if (pnode->todo) nodes.push_back(pnode);
10982 }
10983 }
10984 }
10985 470 return false;
10986 }
10987
10988 /*
10989 Test if the result order is deterministic for a JOIN table list.
10990
10991 @retval false not deterministic
10992 @retval true deterministic
10993 */
10994 694 bool is_order_deterministic(const mem_root_deque<TABLE_LIST *> *join_list,
10995 Item *cond, ORDER *order) {
10996 /*
10997 join_list->is_empty() means this is a UNION with a global LIMIT,
10998 always mark such statements as non-deterministic, although it
10999 might be deterministic for some cases (for example, UNION DISTINCT
11000 with ORDER BY a unique key of both side of the UNION).
11001 */
11002
3/4
✓ Branch 0 taken 694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 693 times.
694 if (join_list->empty()) return false;
11003
11004
1/2
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
693 Join_node root(join_list, cond, order);
11005
1/2
✓ Branch 0 taken 693 times.
✗ Branch 1 not taken.
693 return root.is_ordered();
11006 693 }
11007
11008 /*
11009 Test if the result order is deterministic for a single table.
11010
11011 @retval false not deterministic
11012 @retval true deterministic
11013 */
11014 138 bool is_order_deterministic(TABLE_LIST *table, Item *cond, ORDER *order) {
11015
4/4
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 103 times.
✓ Branch 2 taken 8 times.
✓ Branch 3 taken 27 times.
138 if (order == NULL && cond == NULL) return false;
11016
11017
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 Join_node root(table, cond, order);
11018
1/2
✓ Branch 0 taken 130 times.
✗ Branch 1 not taken.
130 return root.is_ordered();
11019 130 }
11020
11021 /**
11022 Open and lock transactional system tables for read.
11023
11024 One must call close_trans_system_tables() to close systems tables opened
11025 with this call.
11026
11027 @param thd Thread context.
11028 @param table_list List of tables to open.
11029
11030 @note THR_LOCK deadlocks are not possible here because of the
11031 restrictions we put on opening and locking of system tables for writing.
11032 Thus, the system tables can be opened and locked for reading even if some
11033 other tables have already been opened and locked.
11034
11035 @note MDL-deadlocks are possible, but they are properly detected and
11036 reported.
11037
11038 @note Row-level deadlocks should be either avoided altogether using
11039 non-locking reads (as it is done now for InnoDB), or should be correctly
11040 detected and reported (in case of other transactional SE).
11041
11042 @note It is now technically possible to open non-transactional tables
11043 (MyISAM system tables) using this function. That situation might still happen
11044 if the user run the server on the elder data-directory or manually alters the
11045 system tables to reside in MyISAM instead of InnoDB. It will be forbidden in
11046 the future.
11047
11048 @return Error status.
11049 */
11050
11051 39591 bool open_trans_system_tables_for_read(THD *thd, TABLE_LIST *table_list) {
11052 uint counter;
11053 39591 uint flags = MYSQL_OPEN_IGNORE_FLUSH | MYSQL_LOCK_IGNORE_TIMEOUT;
11054
11055
1/2
✓ Branch 0 taken 39591 times.
✗ Branch 1 not taken.
39591 DBUG_TRACE;
11056
11057
2/4
✓ Branch 0 taken 39591 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39591 times.
39591 assert(!thd->is_attachable_ro_transaction_active());
11058
11059 // Begin attachable transaction.
11060
11061
1/2
✓ Branch 0 taken 39591 times.
✗ Branch 1 not taken.
39591 thd->begin_attachable_ro_transaction();
11062
11063 // Open tables.
11064
11065
3/4
✓ Branch 0 taken 39591 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5 times.
✓ Branch 3 taken 39586 times.
39591 if (open_tables(thd, &table_list, &counter, flags)) {
11066
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 thd->end_attachable_transaction();
11067 5 return true;
11068 }
11069
11070 // Check the tables.
11071
11072
2/2
✓ Branch 0 taken 77054 times.
✓ Branch 1 taken 39586 times.
116640 for (TABLE_LIST *t = table_list; t; t = t->next_global) {
11073 // Ensure the t are in storage engines, which are compatible with the
11074 // attachable transaction requirements.
11075
11076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 77054 times.
77054 if ((t->table->file->ha_table_flags() & HA_ATTACHABLE_TRX_COMPATIBLE) ==
11077 0) {
11078 // Crash in the debug build ...
11079 assert(!"HA_ATTACHABLE_TRX_COMPATIBLE is not set");
11080
11081 // ... or report an error in the release build.
11082 my_error(ER_UNKNOWN_ERROR, MYF(0));
11083 thd->end_attachable_transaction();
11084 return true;
11085 }
11086
11087 // The table should be in a transaction SE. This is not strict requirement
11088 // however. It will be make more strict in the future.
11089
11090
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 77052 times.
77054 if (!t->table->file->has_transactions())
11091
8/16
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 2 times.
✗ Branch 11 not taken.
✓ Branch 12 taken 2 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 2 times.
✗ Branch 15 not taken.
2 LogErr(WARNING_LEVEL, ER_SYSTEM_TABLE_NOT_TRANSACTIONAL,
11092 static_cast<int>(t->table_name_length), t->table_name);
11093 }
11094
11095 // Lock the tables.
11096
11097
3/4
✓ Branch 0 taken 39586 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 39585 times.
39586 if (lock_tables(thd, table_list, counter, flags)) {
11098
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 thd->end_attachable_transaction();
11099 1 return true;
11100 }
11101
11102 // Mark the table columns for use.
11103
11104
2/2
✓ Branch 0 taken 77050 times.
✓ Branch 1 taken 39585 times.
116635 for (TABLE_LIST *tables = table_list; tables; tables = tables->next_global)
11105
1/2
✓ Branch 0 taken 77050 times.
✗ Branch 1 not taken.
77050 tables->table->use_all_columns();
11106
11107 39585 return false;
11108 39591 }
11109
11110 /**
11111 Close transactional system tables, opened with
11112 open_trans_system_tables_for_read().
11113
11114 @param thd Thread context.
11115 */
11116
11117 39585 void close_trans_system_tables(THD *thd) { thd->end_attachable_transaction(); }
11118
11119 /**
11120 A helper function to close a mysql.* table opened
11121 in an auxiliary THD during bootstrap or in the main
11122 connection, when we know that there are no locks
11123 held by the connection due to a preceding implicit
11124 commit.
11125
11126 This function assumes that there is no
11127 statement transaction started for the operation
11128 itself, since mysql.* tables are not transactional
11129 and when they are used the binlog is off (DDL
11130 binlogging is always statement-based.
11131
11132 We need this function since we'd like to not
11133 just close the system table, but also release
11134 the metadata lock on it.
11135
11136 Note, that in LOCK TABLES mode this function
11137 does not release the metadata lock. But in this
11138 mode the table can be opened only if it is locked
11139 explicitly with LOCK TABLES.
11140 */
11141
11142 126920 void close_mysql_tables(THD *thd) {
11143 /* No need to commit/rollback statement transaction, it's not started. */
11144
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 127027 times.
126920 assert(thd->get_transaction()->is_empty(Transaction_ctx::STMT));
11145 127027 close_thread_tables(thd);
11146 127075 thd->mdl_context.release_transactional_locks();
11147 127081 }
11148
11149 /**
11150 Open a log table.
11151 Opening such tables is performed internally in the server
11152 implementation, and is a 'nested' open, since some tables
11153 might be already opened by the current thread.
11154 The thread context before this call is saved, and is restored
11155 when calling close_log_table().
11156 @param thd The current thread
11157 @param one_table Log table to open
11158 @param [out] backup Temporary storage used to save the thread context
11159 */
11160 37891 TABLE *open_log_table(THD *thd, TABLE_LIST *one_table,
11161 Open_tables_backup *backup) {
11162 37891 uint flags = (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |
11163 MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY | MYSQL_OPEN_IGNORE_FLUSH |
11164 MYSQL_LOCK_IGNORE_TIMEOUT | MYSQL_LOCK_LOG_TABLE);
11165 TABLE *table;
11166
1/2
✓ Branch 0 taken 37891 times.
✗ Branch 1 not taken.
37891 DBUG_TRACE;
11167
11168
1/2
✓ Branch 0 taken 37891 times.
✗ Branch 1 not taken.
37891 thd->reset_n_backup_open_tables_state(backup,
11169 Open_tables_state::SYSTEM_TABLES);
11170
11171
3/4
✓ Branch 0 taken 37891 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 37888 times.
✓ Branch 3 taken 3 times.
37891 if ((table = open_ltable(thd, one_table, one_table->lock_descriptor().type,
11172 flags))) {
11173
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37888 times.
37888 assert(table->s->table_category == TABLE_CATEGORY_LOG);
11174 /* Make sure all columns get assigned to a default value */
11175
1/2
✓ Branch 0 taken 37888 times.
✗ Branch 1 not taken.
37888 table->use_all_columns();
11176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37888 times.
37888 assert(table->no_replicate);
11177 } else
11178
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 thd->restore_backup_open_tables_state(backup);
11179
11180 37891 return table;
11181 37891 }
11182
11183 /**
11184 Close a log table.
11185 The last table opened by open_log_table()
11186 is closed, then the thread context is restored.
11187 @param thd The current thread
11188 @param backup The context to restore.
11189 */
11190 37888 void close_log_table(THD *thd, Open_tables_backup *backup) {
11191
1/2
✓ Branch 0 taken 37888 times.
✗ Branch 1 not taken.
37888 Query_tables_list query_tables_list_backup;
11192
11193 /*
11194 In order not affect execution of current statement we have to
11195 backup/reset/restore Query_tables_list part of LEX, which is
11196 accessed and updated in the process of closing tables.
11197 */
11198
1/2
✓ Branch 0 taken 37888 times.
✗ Branch 1 not taken.
37888 thd->lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
11199
1/2
✓ Branch 0 taken 37888 times.
✗ Branch 1 not taken.
37888 close_thread_tables(thd);
11200
1/2
✓ Branch 0 taken 37888 times.
✗ Branch 1 not taken.
37888 thd->lex->restore_backup_query_tables_list(&query_tables_list_backup);
11201
1/2
✓ Branch 0 taken 37888 times.
✗ Branch 1 not taken.
37888 thd->restore_backup_open_tables_state(backup);
11202 37888 }
11203
11204 /**
11205 @} (end of group Data_Dictionary)
11206 */
11207